콘센트 주세요.

15579 단어
지난번에 우리는 setInterval을 사용하는 간단한 타이머를 토론했다.위대하다그래서 이 프로그램의 초시계가 생겼어요.그런데 어떻게 우리 시청자들에게 전파될까?해결 방법은 콘센트를 사용하는 것이다.내 Express 백엔드에는 애플리케이션과 동일한 포트에 소켓 서버가 통합되어 있어 모든 것이 즐겁게 공존할 수 있습니다.그래서 기본적으로 모든 것이 emit 사건에 잘 포장되어 있다.우리는 본 블로그에서 채팅 기능과 내가 다음에 어떻게 타이머 장면을 만드는지 소개할 것이다.
이 프로젝트는 여러 개의 채팅방과 개인 채팅방이 필요하다. (그러나 배우가 서로 다른 시간에 서로 다른 컴퓨터에서 교환되면서 이런 개인 채팅방은 다용도로 사용된다.)백엔드의 기본 설정은 React 갈고리를 떠올리게 한다.만약 내가 완전히 성실할 수 있다면, 이것은 나에게 있어서 신기술이기 때문에 따뜻하고 모호한 느낌을 주었다.나는 서버가 노드에서 응용 프로그램과 대화하는 것을 어떻게 확보하는지 깊이 토론하지 않을 것이다. 이것은 이 용례 내부에 대한 회고이다.수시로 다른 정보에 연락하세요
그래서 당신이 해야 할 첫 번째 일은 연결을 확보하는 것이다...일리가 있다...네가 가장 필요로 하는 것은 연결을 끊는 것을 확보하는 것이다.ooo는 기본적으로 되돌아오는 효과를 사용합니다...흥미로운 것은 앞부분이 이런 장면을 모방한다는 것이다.
그래서 백엔드가 가장 간단한 사용 방식이다.

module.exports = (function (app, port) {
    const server = require('http').createServer(app);
    const options = {
        cors: {
            origin: '*',
        }
    };

    const io = require('socket.io')(server, options);
    server.listen(port);

    io.on("connection", (socket) => {

        const { roomId, username } = socket.handshake.query;

        socket.join(roomId);

socket.on("disconnect", () => {
            socket.leave(roomId);
        });
    })

}
)        

빠른 질문이 나올 수도 있어요...응용 프로그램과 포트란...이것은 주 프로그램에서 전송될 것입니다.js (플러그인을 단독 파일에 저장하는 것을 선택했습니다. 혼란스러울 수 있습니다.) 프로그램은 빠른 호출일 뿐입니다. 포트는 다를 것입니다. 기본 포트를 5000으로 설정하지만,heroku의 배치는 배치에 따라 달라집니다.Cors는 이성적으로 * 로 설정되므로 프로덕션 환경 어디에서나 사용할 수 있으며 관리형 위치로 설정할 수 있습니다.
다음 질문, 룸메이트와 사용자 이름은 도대체 어디에서 왔습니까?응용 프로그램의 나머지 부분에 대해 말하자면, 이것은 더욱 복잡한 이야기이기 때문에, 우리는 여기서 너무 많은 것을 깊이 토론하지 않을 것이다.사용자 이름은 그들의 등록에서 왔고, Redux를 통해 전파되었다. 룸Id는 사실상 그들이 우리의 작은 게임에서 차지하는 위치이지만, 지금은 그들의 용도를 다시 조정할 수 있다.악수하다.조회는 가장 중요한 부분이다.악수는 React에서 시작되며 조회는 우리가 정보를 전달하는 곳이다.
우리의 앞머리에 대해...나는 흥겹게 자신의 갈고리를 구축했지만, 많은 표준화 라이브러리에서 socket과immer를 사용한다.하지만 우리의 갈고리는 이렇게 변한다.
import { useEffect, useRef, useState} from "react";
import socketIOClient from "socket.io-client";



const SOCKET_SERVER_URL = `/`;

const useChat = (roomId, username) => {
    const socketRef = useRef();

    useEffect(() => {
        socketRef.current = socketIOClient(SOCKET_SERVER_URL, {
            query: { roomId, username }
        });
 return () => {
            socketRef.current.disconnect();
        };
    }, [roomId]);
}
export {useChat}
여기서 사용하는 것은 socketIOClient의 React 라이브러리입니다.그것은 우리를 위해 많은 일을 했다.
플러그인 서버 URL은 "/"으로 설정됩니다. 왜냐하면 저희 서버 (로컬 호스트와 배치에 적용되는 버전) 를 기반으로 하기 때문입니다. 그러나 이것은 우리가 말한 악수입니다.socketIOClient 호출에서 roomId와 사용자 이름을 사용하여 검색합니다. 연결에서 발생합니다.또한 socketRef가useRef () 의 일부인 이유를 물어볼 수도 있습니다. 그러면useRef () 는 강제로 다시 과장하지 않습니다. 만약 소켓 호출이 특정한 메시지를 보내면, 이것은 우리를 얄미운 소용돌이에 빠뜨릴 수 있습니다.그리고 앞에서 마운트 해제를 언급했습니다. (그들은 왜 마운트 해제라고 부르지 않습니까?!)만일을 대비해서 우리를 밖으로 가두기 위해 끊어진 연락이 있었다.왜 내가 룸메이트를 부속품으로 거기에 두었는지 물어볼지도 몰라요.사실, 우리는 여러 개의 방이 있는데, 여러 막이 있기 때문에, 우리는 3막에서 누군가가 2막의 사람과 이야기하는 것을 원하지 않는다. 스포일러!
이것은 갈고리이기 때문에, React 구성 요소에서 그것을 호출합니다. 이것이 바로 제 채팅방의 설정입니다.이것은 숙주 구성 요소에 나타나기 위해 정보를 되돌려야 한다는 것을 의미한다.우리는 또 백엔드에서 어떤 기능을 제공해야 한다.채팅을 시작하고 실행하기 위해서 우리는 양쪽에서 발송과 수신을 해야 한다...그 다음에 플러그인 함수는 그것을 구성 요소로 되돌려야 합니다.
따라서 React에서 메시지를 가져오고 보내는 기능을 추가합니다.전체 파일은 다음과 같이 보입니다.
import { useEffect, useRef, useState } from "react";
import socketIOClient from "socket.io-client";

const NEW_CHAT_MESSAGE_EVENT = "newChatMessage"; 
const SOCKET_SERVER_URL = `/`;



const useChat = (roomId, username) => {
    const [messages, setMessages] = useState([]); 
    const socketRef = useRef();

    useEffect(() => {
        socketRef.current = socketIOClient(SOCKET_SERVER_URL, {
            query: { roomId, username }
        });

        socketRef.current.on(NEW_CHAT_MESSAGE_EVENT, (message) => {

            const incomingMessage = {
                ...message,
                ownedByCurrentUser: message.senderId === socketRef.current.id,
            };

            setMessages((messages) => [...messages, incomingMessage]);
        });

        return () => {

            socketRef.current.disconnect();
        };
    }, [roomId]);

    const sendMessage = (messageBody) => {
        socketRef.current.emit(NEW_CHAT_MESSAGE_EVENT, {
            body: messageBody,
            senderId: socketRef.current.id,
        });
        return {
            body: messageBody,
            senderId: socketRef.current.id,
        }

    };

    return { messages, sendMessage};
};


export {useChat};
메시지가 추가되었을 때, 우리는 모든 메시지를 되돌려주고, 메시지를 메시지체로 보낼 수 있습니다.senderId는 플러그인으로 만들어졌습니다. 나중에 다시 연결하고 렌더링할 때 문제가 생겼습니다.이것이 바로 사용자 이름의 출처이지만, 우리는 다음에 다시 토론할 것이다.
봐봐. 우리 다 socketRef에 있어.현재(이것은 통로)이지만 우리는 두 가지 기능을 가지고 있다.부단히발사하다.'. on' 은 사용한 전류가 이 소켓을 들을 때 호출되는 것을 가리킨다.그것을 보내고 있습니다.우리가 socket 조회에 그것을 추가한 이래로, 이 두 개는 모두 우리 방에 봉인되어 있다.
이제 백엔드가 이 문제를 어떻게 처리하는지 봅시다.
const NEW_CHAT_MESSAGE_EVENT = "newChatMessage";

socket.on(NEW_CHAT_MESSAGE_EVENT, (data) => {

            io.in(roomId).emit(NEW_CHAT_MESSAGE_EVENT, data);

        });
잠깐만, 이건 그냥 기능이야...확실하게우리는 채팅 프로그램을 낙관적으로 보여주는 것이 아니라 채널에서 발사한다.따라서 백엔드에서 메시지를 받을 때마다 메시지를 보냅니다.발송자를 제외한 모든 사람에게 보낼 수 있는 플러그인 함수도 있지만, 나는 그것을 보내지 않기로 결정했다. 왜냐하면 나는 가정 네트워크에서 그것을 테스트했기 때문에, 이것은 너무 많은 오보가 발생할 것이라고 생각했기 때문이다.그래서 매번 메시지를 받을 때마다 우리가 가입한 현재 방의 모든 콘센트에 메시지를 보냅니다.방의 이름이 매우 구체적이기 때문에, 우리는 그들이 정확한 곳으로 갔는지 확정할 수 있다.이것은 우리의 맞춤형 갈고리가 되돌아오는 메시지 그룹에 업데이트됩니다. 우리는useRef가 있기 때문에 모든 것을 만족시킬 수 있고 다시 과장할 필요가 없습니다.
채팅 구성 요소를 빠르게 미화하기 위해서,submit이나 클릭 프로세서가sendMessage 함수를 수신하고, 메시지 본문을 설정하면 됩니다. 제 글에는 기본적으로 산열된 id가 아닌 사용자 이름을 추가했습니다.그런 다음 이러한 정보를 제공합니다.용례가 다를 수 있습니다.다음에 우리는 이런 발송 시간의 어리석은 방식에 들어갈 것이다.

좋은 웹페이지 즐겨찾기