websocket の echo server を作ってみた

目的

  • html5 の websocket を使って簡単な通信をしてみる

ソース

websocket.html

  1 <!DOCTYPE html>
  2 
  3 <html>
  4 
  5 <head>
  6   <meta charset="utf-8">
  7 
  8   <script type="text/javascript">
  9     var ws = new WebSocket("ws://localhost:8080/");
 10 
 11     ws.onopen = function(event) {
 12       alert("websocket " + event + " is opened");
 13     };
 14 
 15     ws.onmessage = function(event) {
 16       alert(event.data);
 17     };
 18 
 19     function send() {
 20       var msg = document.getElementById("msg").value;
 21       ws.send(msg);
 22     }
 23 
 24   </script>
 25 </head>
 26 
 27 <body>
 28   <input type="text" id="msg" />
 29   <button onclick="send();">send</button>
 30 </body>
 31 
 32 </html>

echo_server.py

  1 import socket
  2 
  3 BUFSIZE = 4096
  4 
  5 host = socket.gethostbyname('localhost')
  6 port = 8080
  7 
  8 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  9 sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 10 sock.bind((host, port))
 11 sock.listen(1)
 12 
 13 print 'waiting for connection...'
 14 
 15 (client_sock, client_addr) = sock.accept()
 16 msg = client_sock.recv(BUFSIZE)
 17 
 18 [head, body] = msg.split("\r\n", 1)
 19 header = {}
 20 
 21 for line in body.splitlines():
 22   if line == "":
 23     break
 24   else:
 25     [key, value] = line.split(": ", 1)
 26     header[key] = value.strip()
 27 
 28 # websocket handshake
 29 handshake  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n"
 30 handshake += "Upgrade: %s\r\n" % header['Upgrade']
 31 handshake += "Connection: %s\r\n" % header['Connection']
 32 handshake += "WebSocket-Origin:%s\r\n" % header['Origin']
 33 handshake += "WebSocket-Location: ws://localhost:8080/\r\n"
 34 handshake += "\r\n"
 35 
 36 client_sock.send(handshake)
 37 
 38 print 'connection start'
 39 print '---------- ---------- ----------'
 40 
 41 while True:
 42   msg = client_sock.recv(BUFSIZE)
 43 
 44   if msg == "":
 45     break
 46   else:
 47     print "client: %s" % msg[0:len(msg)-1]
 48     client_sock.send(msg)
 49 
 50 client_sock.close()
 51 
 52 sock.close()
 53   
 54 print '---------- ---------- ----------'
 55 print 'connection end'
 56     

実行

  • chrome から文字列を送ってみる
connection start
---------- ---------- ----------
client: this
client: is
client: a
client: test
---------- ---------- ----------
connection end

考察

  • そもそも最初は通信自体がうまくいなかった
    • handshake を行わないと通信を確立してくれない
  • 47行目で受け取った文字列の後ろ2バイトを削っている
    • 終端文字として何か入ってるみたいだが文字化けするので削った


参考