WebSocket使用教程 - 带完整实例(收藏)

什么是WebSocket?看过html5的同学都知道,WebSocket protocol 是HTML5一种新的协议。它是实现了浏览器与服务器全双工通信(full-duplex)。HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽并达到实时通讯。现在我们来探讨一下html5的WebSocket

jquery-min.js" type="text/javascript">

var ws;

function ToggleConnectionClicked() {

try {

ws = new WebSocket("ws://10.9.146.31:1818/chat");//连接服务器

ws.onopen = function(event){alert("已经与服务器建立了连接rn当前连接状态:"+this.readyState);};

ws.onmessage = function(event){alert("接收到服务器发送的数据:rn"+event.data);};

ws.onclose = function(event){alert("已经与服务器断开连接rn当前连接状态:"+this.readyState);};

ws.onerror = function(event){alert("WebSocket异常!");};

}catch(ex) {

alert(ex.message);

}

};

function SendData() {

try{

ws.send("beston");

}catch(ex){

alert(ex.message);

}

};

function seestate(){

alert(ws.readyState);

}

连接服务器

发送我的名字:beston

查看状态

服务器端代码:

代码如下复制代码

using System;

using System.Net;

using System.Net.Sockets;

using System.Security.Cryptography;

using System.Text;

using System.Text.RegularExpressions;

namespace WebSocket

{

class Program

{

static void Main(string[] args)

{

int port = 1818;

byte[] buffer = new byte[1024];

IPEndPoint localEP = new IPEndPoint(IPAddress.Any, port);

Socket listener = new Socket(localEP.Address.AddressFamily,SocketType.Stream, ProtocolType.Tcp);

try{

listener.Bind(localEP);

listener.Listen(10);

Console.WriteLine("等待客户端连接....");

Socket sc = listener.Accept();//接受一个连接

Console.WriteLine("接受到了客户端:"+sc.RemoteEndPoint.ToString()+"连接....");

//握手

int length = sc.Receive(buffer);//接受客户端握手信息

sc.Send(PackHandShakeData(GetSecKeyAccetp(buffer,length)));

Console.WriteLine("已经发送握手协议了....");

//接受客户端数据

Console.WriteLine("等待客户端数据....");

length = sc.Receive(buffer);//接受客户端信息

string clientMsg=AnalyticData(buffer, length);

Console.WriteLine("接受到客户端数据:" + clientMsg);

//发送数据

string sendMsg = "您好," + clientMsg;

Console.WriteLine("发送数据:“"+sendMsg+"” 至客户端....");

sc.Send(PackData(sendMsg));

Console.WriteLine("演示Over!");

}

catch (Exception e)

{

Console.WriteLine(e.ToString());

}

}

///

/// 打包握手信息

///

/// Sec-WebSocket-Accept

/// 数据包

private static byte[] PackHandShakeData(string secKeyAccept)

{

var responseBuilder = new StringBuilder();

responseBuilder.Append("HTTP/1.1 101 Switching Protocols" + Environment.NewLine);

responseBuilder.Append("Upgrade: websocket" + Environment.NewLine);

responseBuilder.Append("Connection: Upgrade" + Environment.NewLine);

responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);

//如果把上一行换成下面两行,才是thewebsocketprotocol-17协议,但居然握手不成功,目前仍没弄明白!

//responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine);

//responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine);

return Encoding.UTF8.GetBytes(responseBuilder.ToString());

}

///

/// 生成Sec-WebSocket-Accept

///

/// 客户端握手信息

/// Sec-WebSocket-Accept

private static string GetSecKeyAccetp(byte[] handShakeBytes,int bytesLength)

{

string handShakeText = Encoding.UTF8.GetString(handShakeBytes, 0, bytesLength);

string key = string.Empty;

Regex r = new Regex(@"Sec-WebSocket-Key:(.*?)rn");

Match m = r.Match(handShakeText);

if (m.Groups.Count != 0)

{

key = Regex.Replace(m.Value, @"Sec-WebSocket-Key:(.*?)rn", "$1").Trim();

}

byte[] encryptionString = SHA1.Create().ComputeHash(Encoding.ASCII.GetBytes(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"));

return Convert.ToBase64String(encryptionString);

}

///

/// 解析客户端数据包

///

/// 服务器接收的数据包

/// 有效数据长度

///

private static string AnalyticData(byte[] recBytes, int recByteLength)

{

if (recByteLength < 2) { return string.Empty; }

bool fin = (recBytes[0] & 0x80) == 0x80; // 1bit,1表示最后一帧

if (!fin){

return string.Empty;// 超过一帧暂不处理

}

bool mask_flag = (recBytes[1] & 0x80) == 0x80; // 是否包含掩码

if (!mask_flag){

return string.Empty;// 不包含掩码的暂不处理

}

int payload_len = recBytes[1] & 0x7F; // 数据长度

byte[] masks = new byte[4];

byte[] payload_data;

if (payload_len == 126){

Array.Copy(recBytes, 4, masks, 0, 4);

payload_len = (UInt16)(recBytes[2] << 8 | recBytes[3]);

payload_data = new byte[payload_len];

Array.Copy(recBytes, 8, payload_data, 0, payload_len);

}else if (payload_len == 127){

Array.Copy(recBytes, 10, masks, 0, 4);

byte[] uInt64Bytes = new byte[8];

for (int i = 0; i < 8; i++){

uInt64Bytes[i] = recBytes[9 - i];

}

UInt64 len = BitConverter.ToUInt64(uInt64Bytes, 0);

payload_data = new byte[len];

for (UInt64 i = 0; i < len; i++){

payload_data[i] = recBytes[i + 14];

}

}else{

Array.Copy(recBytes, 2, masks, 0, 4);

payload_data = new byte[payload_len];

Array.Copy(recBytes, 6, payload_data, 0, payload_len);

}

for (var i = 0; i < payload_len; i++){

payload_data[i] = (byte)(payload_data[i] ^ masks[i % 4]);

}

return Encoding.UTF8.GetString(payload_data);

}

///

/// 打包服务器数据

///

/// 数据

/// 数据包

private static byte[] PackData(string message)

{

byte[] contentBytes = null;

byte[] temp = Encoding.UTF8.GetBytes(message);

if (temp.Length < 126){

contentBytes = new byte[temp.Length + 2];

contentBytes[0] = 0x81;

contentBytes[1] = (byte)temp.Length;

Array.Copy(temp, 0, contentBytes, 2, temp.Length);

}else if (temp.Length < 0xFFFF){

contentBytes = new byte[temp.Length + 4];

contentBytes[0] = 0x81;

contentBytes[1] = 126;

contentBytes[2] = (byte)(temp.Length & 0xFF);

contentBytes[3] = (byte)(temp.Length >> 8 & 0xFF);

Array.Copy(temp, 0, contentBytes, 4, temp.Length);

}else{

// 暂不处理超长内容

}

return contentBytes;

}

}

}

运行效果:

使用的浏览器:

疑问:如实例中

代码如下复制代码

responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine + Environment.NewLine);

//如果把上一行换成下面两行,才是thewebsocketprotocol-17协议,但居然握手不成功,目前仍没弄明白!

//responseBuilder.Append("Sec-WebSocket-Accept: " + secKeyAccept + Environment.NewLine);

//responseBuilder.Append("Sec-WebSocket-Protocol: chat" + Environment.NewLine);

这是为什么呢?看到这篇博文的兄弟希望能够给我解惑!

连接键盘 功能

什么是”连接键盘“功能

”连接键盘“功能其实就是开通了网页版的微信,利用键盘可以快速录入文字聊天。

连接方法很简单,用手机打开微信点击右上角魔术棒,会弹出三个选项,只用选择连接键盘就可以了,这时用浏览器打开wx.qq.com然后用手机扫描网页中的二维码即可打开网页版微信,而这时也就可以直接利用电脑键盘实现快速聊天了。

WebSocket-Server里项目含义如下:

Mobile:手机模拟器,与手机通讯服务器进行UDP通讯,负责提示打开的页面地址,并输入GUID(相当于二维码)与页面进行绑定;

MobileServer:手机通讯服务器,负责接收手机信息(比如微信的账户信息以及二维码信息),此处接收GUID。并转发至WebSocket通讯服务器;

WebSocket:WebSocket通讯服务器,与手机通讯服务器和页面的WebSocket进行通讯;

WebSocket-Client里项目含义如下:

test.html:测试的web页面(类似微信的wx.qq.com);

jquery-1.8.0.min.js:jquery框架;

实现原理

页面test.html生成GUID并存储在WebSocket,手机模拟器输入GUID并传至WebSocket服务器,在WebSocket服务器检索页面Socket信息并通讯。

注意事项

如果自己测试请根据上述步骤先启动手机通讯服务器和WebSocket通讯服务器;

把所有是“10.9.146.31”的字符串更换为自己的IP;

原文地址:http://www.111cn.net/wy/html5/69508.htm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容

  • <!DOCTYPE html> 查看源 window.WRM=window.WRM||{};window....
    SMSM阅读 874评论 1 0
  • 原文在:http://www.king-liu.net, 欢迎大家来 WebSocket protocol 是HT...
    lkinga7阅读 3,554评论 0 17
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,633评论 18 139
  • 提笔画江山,山河荡我心,谁料一席梦,浮生半片山,众矢万难艰,浪人仍依旧。
    画个梦阅读 179评论 0 0
  • 理论 在Apple的文档中,scheme在URL相关的内容中出现过,比如: 紧接着这一段,有如下说明: 详情点击这...
    Mr_Zander阅读 6,623评论 4 4