Fork me on GitHub

WebSocket

背景

最近在做一系列的多人互动小游戏,对比了简单对比了几种实时信息的方案,总结如下。

传统实时信息的获取的方式

由于http是无连接的,一个request 再一个response 生命周期就结束了,服务器不能主动发信息给客户端,
传统的实进信息传输只能通过以下方式达到实时(或伪实时)。

  • [长|短]轮询
  • 基于flash

轮询性能不佳,假实时,flash不安全,safari默认禁止,chrome会在末来弃用.

websocket就是解决这个痛点的。

WebSocket

websocket 允许client与server建立一个全双工通信,api,简单易用。

WebSocket client使用(超级简单)

 var ws = new WebSocket(“ws://echo.websocket.org”); 
 ws.onopen = function(){ws.send(“Test!”); }; 
 ws.onmessage = function(evt){console.log(evt.data);ws.close();}; 
 ws.onclose = function(evt){console.log(“WebSocketClosed!”);}; 
 ws.onerror = function(evt){console.log(“WebSocketError!”);};
 ws.close(); //发起断连请求

server 使用

server端用了npm包 ws,了解协议原理后也再加上ws库,代码量少,使用简单。

[coffee]


WebSocketServer = (require "ws").Server
wss = new WebSocketServer {port:config.websocktport}
console.log "Websocket server listiing on port:" + config.websocktport
wss.on 'open',(rlt)->
	console.log "[wss open]",rlt
wss.on 'connection',(conn)->
	console.log "[websocket connection]"
	conn.on 'open',(rlt)->
		console.log "[websocket open]"
	conn.on 'message',(message)->
	    #blablabal
	conn.on 'close',(rlt)->
		console.log "[websocket close]",rlt
wss.on 'close',(temp)->
	console.log "[wss close]"

由于websocket是长连接,并发大时可用nginx做均衡。详情查看NGINX as a WebSockets Proxy

api

从w3 定义的接口中可以简单明了的查看全部可用的接口。

C++ 接口

[Constructor(DOMString url, optional (DOMString or DOMString[]) protocols)]
interface WebSocket : EventTarget {
  readonly attribute DOMString url;

  // ready state
  const unsigned short CONNECTING = 0;
  const unsigned short OPEN = 1;
  const unsigned short CLOSING = 2;
  const unsigned short CLOSED = 3;
  readonly attribute unsigned short readyState;
  readonly attribute unsigned long bufferedAmount;

  // networking
           attribute EventHandler onopen;
           attribute EventHandler onerror;
           attribute EventHandler onclose;
  readonly attribute DOMString extensions;
  readonly attribute DOMString protocol;
  void close([Clamp] optional unsigned short code, optional DOMString reason);

  // messaging
           attribute EventHandler onmessage;
           attribute DOMString binaryType;
  void send(DOMString data);
  void send(Blob data);
  void send(ArrayBuffer data);
  void send(ArrayBufferView data);
};

协议报文


//用http协议完成握手

GET / HTTP/1.1
Host: testtapp.killerwhale.cn:6002
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
Upgrade: websocket   //websocket 连接
Origin: http://testtapp.killerwhale.cn
Sec-WebSocket-Version: 13
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.63 Safari/537.36
Accept-Encoding: gzip, deflate, sdch
Accept-Language: zh-CN,zh;q=0.8
Sec-WebSocket-Key: y2F08hQkyT/wMfaRdAuNIg==  //Base64 encode
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits

//切换协议
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: N4LBCcppYmmHJJdTuUjxJL4d06U=
Sec-WebSocket-Extensions: permessage-deflate

//data
......Bw...."UB2O'.1.T[..5.."..q.s&.....#.vY....k3\.{...x..X...7.
.k..z&.o..)hy.`.....xv.>z..w>Y1...}..DM-..L..../..D.a!....U....i
..5./......<....G......W.N.'.Vh..<y.B.`..O...9..i..).....k....a....r...
;U]Rk........R.+... f.f...`.'dh..Va.._..5.._...|.S.M.~....AN.@.E.2kSPh.....Di....L.	.03..Vh.Eo..\.x.o.x
.n.{..'PrJ!C`	\...A.......	..f....XAa....f[............8....a..@X..?(.H.2H.B........S.5...j?t
.R....>...W|V2.....J....$.&..F.....s*.B....yQA`.4f......t.v\{..9..@{Bun....V.&0z...<....E.......z......................a.+.k.a..?..&..`._ ..w..f...G.......a.$.VJ...M.KQ.R
.q.
qw.u...p.vU..........j...(...5%s...~.:....).@.)
.A&..j..~....Mn.@.......ZP~v..Tj1.i`cF..0..0`A.....]6..z..k..}.K.;..S
..&XZk7t..K..<.w..@...<..s..F.........	.C...>..(.TX.^%.r..D..`Y.....a.....|.^.n..S\..aZ.m=.e..LIz.fM..>..D.}@Z......}......Mh.9.h.....m?..y..M..:.n..zP.....	C}De.&N_..x.*.r.#..s..|y.a.<I..................".VJ...M.KQ.Rrw.uu.s...p.vU........

参考

  1. WebSocket协议栈
  2. WebSocket API
posted @   路西恩  阅读(385)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
点击右上角即可分享
微信分享提示