Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8875

WebSocket メモ

$
0
0

WebSocket とは

  • クライアントとリモートホストの間で双方向通信を可能とするプロトコル。
  • セキュリティモデルはウェブブラウザでよく用いられるオリジンをベースとしたモデル。
  • XMLHttpRequestやロングポーリングに頼らずにサーバとの双方向通信を必要とするブラウザアプリケーションのためのメカニズムを提供する。
  • クライアント・サーバ間の双方向のトラフィックのためにTCPコネクションを一つだけ張る。

プロトコルの概要

プロトコルはハンドシェイクデータ転送の2つの部分からなる。

ハンドシェイク

クライアント -> サーバ

GET/chatHTTP/1.1Host:server.example.comUpgrade:websocketConnection:UpgradeSec-WebSocket-Key:dGhlIHNhbXBsZSBub25jZQ==Origin:http://example.comSec-WebSocket-Protocol:chat, superchatSec-WebSocket-Version:13

サーバ -> クライアント

HTTP/1.1101Switching ProtocolsUpgrade:websocketConnection:UpgradeSec-WebSocket-Accept:s3pPLMBiTxaQ9kYGzzhZRbK+xOo=Sec-WebSocket-Protocol:chat

ハンドシェイクが成功すると、クライアントとサーバは1つ以上のフレームからなるメッセージをお互いに送出し合うことになる。

Node.js でシンプルな WebSocket 通信

Node.js では、wsというWebSocketライブラリを用いてシンプルな WebSocket 通信ができる(Socket.IOでも可能)。

サーバ側のコード

constWebSocket=require('ws')constserver=newWebSocket.Server({port:3000})server.on('connection',ws=>{ws.send('connected!')ws.on('message',message=>{console.log('received: %s',message)})})

クライアント側のコード

constws=require('ws')constclient=newws('ws://localhost:3000')client.on('open',()=>{client.send('hello')})client.on('message',message=>{console.log(message)})

node server.jsでWebSocketサーバを立ち上げた後 node client.jsを実行すると、サーバ側では

received: hello

と出力され、クライアント側では

connected!

と出力される。

WebSocket でチャットアプリを作る

blessedというクールな CUI を作れるライブラリを使って、超シンプルなチャットアプリ(もどき)を作ってみる。

サーバ側

constWebSocket=require('ws')constserver=newWebSocket.Server({port:3000})constsockets=newMap()constbroadcast=message=>{console.log(message)server.clients.forEach(client=>{if(client.readyState===WebSocket.OPEN){client.send(message)}})}server.on('connection',socket=>{socket.on('message',message=>{if(sockets.has(socket)){constname=sockets.get(socket)broadcast(`${name}: ${message}`)}else{sockets.set(socket,message)broadcast(`${message} entered the room.`)}})socket.on('close',()=>{constname=sockets.get(socket)if(name){sockets.delete(socket)broadcast(`${name} left the room.`)}})})

クライアント側

constws=require('ws')constblessed=require('blessed')constscreen=blessed.screen({smartCSR:true})screen.title='chat'constchatList=blessed.list({border:{type:'line'}})consttextbox=blessed.textbox({height:'10%',bottom:0,input:true,inputOnFocus:true,border:{type:'line'}})constclient=newws('ws://localhost:3000')client.on('open',async()=>{textbox.setText('(Please enter your name)')textbox.focus()screen.render()})client.on('message',message=>{chatList.insertLine(0,message)screen.render()})textbox.key(['enter'],()=>{client.send(textbox.getText())textbox.clearValue()chatList.render()textbox.focus()})constEXIT_COMMANDS=['escape','C-c']constexit=()=>process.exit(0)screen.key(EXIT_COMMANDS,exit)chatList.key(EXIT_COMMANDS,exit)textbox.key(EXIT_COMMANDS,exit)screen.append(chatList)screen.append(textbox)screen.render()

実際の動作

chat.gif

それっぽくは動く。

所感

  • blessed の API がよくわからない
  • ブラウザを UI としたチャットアプリを作ってみたい
  • 随時更新する

出典


Viewing all articles
Browse latest Browse all 8875

Trending Articles