最近要做一个html5的应用,需要实时交互的功能,本来是打算使用Ajax的,但是上网又看到了websocket,既然实时交互,那么socket是再也适合不过的了。奈何网上关于websocket的资料甚少,而且许多demo都是基于已经过时的websocket协议的,于是便只好自己动手,丰衣足食啦~ 先看一下建立连接的请求头和响应头:
websocket的协议的请求头:
GET ws://localhost:12345/websocket/test.php HTTP/1.1
Origin: http://localhost
Connection: Upgrade
Host: localhost:12345
Sec-WebSocket-Key: JspZdPxs9MrWCt3j6h7KdQ==
Upgrade: websocket Sec-WebSocket-Version: 13
websocket的响应头:
HTTP/1.1 101 Web Socket Protocol Handshake
WebSocket-Location: ws://localhost:12345/websocket/test.php
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: zUyzbJdkVJjhhu8KiAUCDmHtY/o=
WebSocket-Origin: http://localhost
从中可看到,之前把版本的websocket请求头是有key1和key2的,现在的版本由Sec-WebSocket-Key代替。
服务器必须根据Sec-WebSocket-Key的内容计算出Sec-WebSocket-Accept以证明收到了浏览器发送的建立连接的请求,计算的方法如下
第一步:将Sec-WebSocket-Key与字符串258EAFA5-E914-47DA-95CA-C5AB0DC85B11(一个标准的字符串)连接
第二步:将第一步生成的字符串进行sha1编码
第三步:将第二步生成的字符串每两个字符分开转换成十六进制数字对应的asc码,然后进行base64编码。
websocket传颂的数据帧的定义如下:
FIN:1 bit,表明该帧是否是消息的最后一帧,为1表示是,0表示否
RSV:3 bit,保留位,用于客户端和服务器之间协定其它的性息时使用,默认都是0
Opcode:4 bit,定义了发送的数据格式,(o000表示一个连续的帧,0001表示文本,00102表示二进制流, 0011~0111为非控制帧保留,1000表示断开连接,1001表示ping命令,1010表示pong命令,1011~1111为其他控制命令帧保留
Mask:1 bit,表明发送的数据是否进行了掩码编码操作,1表示进行了掩码编码,0表示没有(从客户端发送到服务器的数据必须进行掩码编码操作)
Payload len: 7 or 7+16 or 7+64 bit,如果Payload len为1111110,则接下来的16bit代表数据的长度,如果Payload len为1111111,则截下来的64bit代表数据的长度,否则,7位的Payload len代表数据的长度
Mask-key:4 bit,如果数据进行了掩码编码,则包含4 bit的掩码
Payload data:发送的消息
对数据进行掩码操作是将数据按位与掩码异或,将数据从编码后的数据提取出来也是通过与掩码进行异或。
目前仅仅写了一个聊天程序,还不是特别完善,给大家做个参考吧。
代码地址:点击这里