일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- Python
- 스크럼 마스터
- Django
- 파헤쳐보자
- java
- 소켓
- socket.io
- node.js
- Knowledge Graph
- 스크럼
- 지식 그래프
- 개발자
- 노드
- 스레드
- 특징
- benchmark
- node
- 이벤트 루프
- 예제
- 노드js
- scrum
- RDF
- 자바
- nodejs
- Router
- express
- Groovy
- C++
- Stream
- ngrinder
- Today
- Total
라봉이의 개발 블로그
Node.js의 socket.io 클라이언트 파일 경로가 /socket.io/socket.io.js 인 이유 본문
Socket.io
Socket.io란 WebSocket을 기반으로 클라이언트와 서버의 양방향 통신을 가능하게 해주는 모듈입니다. Socket.io를 사용하기 위해선 서버와 클라이언트 모두 Socket.io 라이브러리가 필요합니다.
socket.io 문서를 보면 client에서 socket.io 라이브러리를 html script로 불러올 때 다음 코드를 작성하도록 하게 합니다.
<script src="/socket.io/socket.io.js"></script>
문제는 Node.js 서버 개발 시에는 저런 파일을 정적(static)으로 제공한 적도, 저 파일을 만든 적도 없는데 사용할 수 있다는 것입니다.
socket.io 서버
위에서 작성한 코드는 웹 클라이언트에서 상대 경로에 있는 socket.io.js 파일을 서버 측에 요청하는 코드입니다. 그렇다면 Node.js 서버에서는 static 파일을 제공하는 코드를 작성해야 하는데, 먼저 socket.io 문서에서 제공하는 서버 측 코드를 보시면 좋을 것 같습니다.
// CommonJS
const httpServer = require("http").createServer();
const io = require("socket.io")(httpServer, {
// ...
});
io.on("connection", (socket) => {
// ...
});
httpServer.listen(3000);
위의 코드는 express.js나 nest.js 웹 프레임워크를 사용하지 않는 코드입니다.
위의 코드를 보면 알 수 있듯이, 기존 http 서버 인스턴스를 socket.io 라이브러리 인스턴스의 프로퍼티로 넣는 것을 확인할 수 있습니다.
이번엔 express.js 서버에서 사용하는 코드입니다.
const app = require("express")();
const httpServer = require("http").createServer(app);
const options = { /* ... */ };
const io = require("socket.io")(httpServer, options);
io.on("connection", socket => { /* ... */ });
httpServer.listen(3000);
마찬가지로 기존 express http 서버 인스턴스를 socket.io 라이브러리 인스턴스의 프로퍼티로 넣습니다.
이로써 우리는 http 서버 인스턴스를 사용해 socket.io를 사용할 수 있도록 하는 것을 추측할 수 있습니다.
socket.io.js는 어디에 있을까?
그렇다면 socket.io 내부에서는 기존 http 서버 인스턴스를 어떻게 활용하길래, socket.io.js 파일을 제공할 수 있었던 건 지 알아봐야 할 것 같습니다.
일단 node_modules
디렉토리에 있을 것 같아 socket.io의 디렉토리를 확인해보니 서브 디렉토리 client-dist
에 socket.io.js 파일이 있는 것을 확인했습니다.
그렇다면 socket.io 라이브러리 내에 client-dist 경로의 파일을 static 파일로 제공할 것 같아 socket.io github에 "client-dist" 를 검색해보니 다음과 같은 코드가 검색됐습니다.
private serve(req: http.IncomingMessage, res: http.ServerResponse): void {
const filename = req.url!.replace(this._path, "");
const isMap = dotMapRegex.test(filename);
const type = isMap ? "map" : "source";
// Per the standard, ETags must be quoted:
// https://tools.ietf.org/html/rfc7232#section-2.3
const expectedEtag = '"' + clientVersion + '"';
const weakEtag = "W/" + expectedEtag;
const etag = req.headers["if-none-match"];
if (etag) {
if (expectedEtag === etag || weakEtag === etag) {
debug("serve client %s 304", type);
res.writeHead(304);
res.end();
return;
}
}
debug("serve client %s", type);
res.setHeader("Cache-Control", "public, max-age=0");
res.setHeader(
"Content-Type",
"application/" + (isMap ? "json" : "javascript")
);
res.setHeader("ETag", expectedEtag);
if (!isMap) {
res.setHeader("X-SourceMap", filename.substring(1) + ".map");
}
Server.sendFile(filename, req, res);
}
위의 코드를 보면 알 수 있듯이, socket.io 서버 측 라이브러리에는 기존 http 서버를 활용해서, node_modules/socket.io/client-dist 경로에 있는 socket.io.js를 제공하는 함수 serve
가 있다는 것을 알 수 있습니다.
socket.io를 create 할 시에 node.js의 http 서버를 생성자로 받기에 이러한 코드가 있을 것 같은 예상을 하긴 했었지만 코드를 보니 확신할 수 있었습니다.
물론 socket.io.js 파일의 경로와 클라이언트에서 요청하는 socket.io.js파일의 경로가 다르지만, replace
을 이용해 요청받은 url의 경로를 socket.io.js파일의 경로로 변경하는 것을 알 수 있습니다.
결론
따라서 마무리 요약하자면 다음으로 정리할 수 있을 것 같습니다.
- socket.io 라이브러리 내부에 클라이언트에서 사용하는 socket.io.js 파일이 존재한다.
- 서버 측 socket.io는 기존 http 서버 인스턴스를 프로퍼티로 받아, 업그레이드 한다.
- 업그레이드 된 socket.io 서버는 socket.io.js 파일을 serve 할 수 있게 된다.
'Node.js' 카테고리의 다른 글
single thread인 Node.js에서 thread 생성하기 1 - worker_thread 모듈 (2) | 2019.02.16 |
---|---|
Node.js에서 async await를 사용해야 하는 이유 (0) | 2018.09.15 |
chalk: 로그에 색을 입혀보자. (pm2에서의 색 나오지 않는 오류) (0) | 2018.08.07 |
[Node.js][노드] stream(스트림) 이란?? (2) | 2018.06.08 |
nodejs fs 모듈 open 함수, stat 함수, read 함수. 파일 중간 위치에서 파일 읽기 (0) | 2018.05.21 |