웹소켓은 웹 환경에서 웹소켓 클라이언트로 사용하는 예제이다.1
작성자: ospace114@empal.com, http://ospace.tistory.com/
var ws = new WebSocket('ws://localhost:3001');
ws.onopen = function (event) {
ws.send("Client message: Hi!");
}
ws.onmessage = function (event) {
console.log("Server message: ", event.data);
}
ws.onerror = function (event) {
console.log("Server error message: ", event.data);
}
웹소켓 서버
웹소켓 서버 구현하기 위해서는 ws 패키지를 사용했다.
const ws = require('ws');
const wsServer = new ws.Server({port:3001});
wsServer.on('connection', function(socket) {
socket.send("Hello! I am a server.");
socket.on("message", function(message) {
console.log("Received: %s", message);
});
});
http 서버와 같이 사용하는 경우이다.
const fs = require('fs');
const https = require('https');
const ws = require('ws');
const server = https.createServer({
cert: fs.readFileSync('/path/to/cert.pem'),
key: fs.readFileSync('/path/to/key.pem')
});
const wss = new ws.Server({ server });
wss.on('connection', function connection(socket) {
socket.on('message', function incoming(message) {
console.log('received: %s', message);
});
socket.send('something');
});
server.listen(8080);
socket.io 사용
socket.io 사용하는 방법이 있다. 일반적인 웹소켓은 예전 브라우저에서는 지원하지 않기에 호환성은 socket.io가 더 좋다.
이는 브라우저 기본 지원은 아니기 때문에 별도로 js 추가해서 사용해야한다. socket.io에서 각 브라우저 기술을 파악해서 적합한 기술을 선택해서 통신한다.
npm i socket.io
일단 express.js를 사용한다고 간주하겠다.
서버코드는 다음과 같다.
var socketIo = require('socket.io');
var http = require('http');
var server = http.createServer(app);
const io = new socketIo.Server(server);
//const io = socketIo(3000);
io.on('connection', (socket) => {
console.log('a user connected');
});
클라이언트 코드는 다음과 같다.
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.1.3/socket.io.min.js"></script>
<script type="text/javascript">
const socket = io();
</script>
사용자 단위로 관리
특정사용자에 대한 데이터 관리하는 예제이다.
const sockets = {};
function sendTo(user, data) {
if(sockets[user] && sockets[user].readyState === WebSocket.OPEN)
sockets[user].send(data);
}
wss.on('connection', (socket) => {
const userId = userIdOf(socket);
sockets[userId] = socket;
socket.on('message', function incoming(message) {
// userId로 처리 가능
});
socket.on('close', function incoming(message) {
delete sockets[userId];
});
});
userIdOf()은 자신의 메시지에 맞게 구현해주면 된다.
접근 관리
server.on('upgrade', function(req, socket, head) {
const pathname = url.parse(req.url).pathname;
let remoteIp = req.headers['x-forwarded-for'] || req.socket.remoteAddress;
let protocol = req.headers['sec-websocket-protocol'];
// 인증 검증
const auth = protocol && jwt.verify(protocol);
if (!auth) {
console.error(`unauthorized from ${remoteIp}: ${protocol}`);
socket.write('HTTP/1.1 401 Unauthorized\r\n\r\n');
socket.destroy();
return;
}
console.log(auth);
console.log(`authorized from ${remoteIp} by userId[${auth.userId}]`);
// 경로 확인
if(pathname === '/alarms') {
wsServer.handleUpgrade(req, socket, head, function(conn) {
wsServer.emit('connection', conn, auth);
})
} else {
console.error('invalid upgrade:', pathname);
socket.destroy();
}
});
var sockets = {};
const wsServer = new ws.Server({noServer:true});
wsServer.on('connection', function(socket, req) {
let userId = userIdOf(req);
sockets[userId] = socket;
console.log(`ws connected - userId[${userId}]`);
socket.on("message", function(message) {
console.log("Received: %s", message);
});
socket.on('error', function(err:any) {
console.error(`ws error - userId[${userId}]`, err);
});
socket.on('close', function(ws:any) {
delete sockets[userId];
})
});
참고
[1] https://poiemaweb.com/nodejs-socketio
[2] https://medium.com/@raj_36650/integrate-socket-io-with-node-js-express-2292ca13d891
반응형
'3.구현 > HTML5&Javascript' 카테고리의 다른 글
Javascript XLSX 파일 읽기 (0) | 2021.12.24 |
---|---|
[node.js] 단위테스트 사용하기 (0) | 2021.11.15 |
[vue2] package 버전 및 빌드시간 사용 (0) | 2021.11.15 |
[vue2] vuetify 기본 구성 (0) | 2021.11.11 |
[vue2] vuex 사용하기 (0) | 2021.11.10 |