定义:

遵循RFC6544协议的通信协议。Webcoket协议和http协议属于并行关系,但是websocket是以http协议为基础开发出来的(微软用IhttpHandler接口中同时处理这两种协议),同时他们都是以TCP协议为基础。可以进行双向通信、持久化通信。Http是单向通信协议、无状态通信。

websocket协议(握手部分):

GET /chat HTTP/1.1
Host: http://server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

比http握手多了几个部分:

Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

这几个部分告诉服务器,该请求是Webcoket,不是http了。

接收的数据

GET /chat HTTP/1.1
Host: http://example.com:8000
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

发送的数据

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

服务端:

  • 使用第三方的Fleck库,建议采用吧,比较方便。
  • 使用第三方的websocketsharp库,不方便服务端主动推送数据到客户端。
  • 自己按照RFC6544协议,打包协议头+socket API库,收发数据。
  • 使用IIS8.0以上可以处理websocket请求:
namespace SimpleWebSocketApplication
{ public class WebSocketHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { //Checks if the query is WebSocket request.  if (context.IsWebSocketRequest) { //If yes, we attach the asynchronous handler. context.AcceptWebSocketRequest(WebSocketRequestHandler); } } public bool IsReusable { get { return false; } } //Asynchronous request handler. public async Task WebSocketRequestHandler(AspNetWebSocketContext webSocketContext) { //Gets the current WebSocket object. WebSocket webSocket = webSocketContext.WebSocket; /*We define a certain constant which will represent size of received data. It is established by us and  we can set any value. We know that in this case the size of the sent data is very small. */ const int maxMessageSize = 1024; //Buffer for received bits. var receivedDataBuffer = new ArraySegment<Byte>(new Byte[maxMessageSize]); var cancellationToken = new CancellationToken(); //Checks WebSocket state. while (webSocket.State == WebSocketState.Open) { //Reads data. WebSocketReceiveResult webSocketReceiveResult = await webSocket.ReceiveAsync(receivedDataBuffer, cancellationToken); //If input frame is cancelation frame, send close command. if (webSocketReceiveResult.MessageType == WebSocketMessageType.Close) { await webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, String.Empty, cancellationToken); } else { byte[] payloadData = receivedDataBuffer.Array.Where(b => b != 0).ToArray(); //Because we know that is a string, we convert it. string receiveString = System.Text.Encoding.UTF8.GetString(payloadData, 0, payloadData.Length); //Converts string to byte array. var newString = String.Format("Hello, " + receiveString + " ! Time {0}", DateTime.Now.ToString()); Byte[] bytes = System.Text.Encoding.UTF8.GetBytes(newString); //Sends data back. await webSocket.SendAsync(new ArraySegment<byte>(bytes), WebSocketMessageType.Text, true, cancellationToken); } } } }
}
  • 使用TcpListener类库,不能使用httpListener类库,,创建监听,并将发送的数据按RFC6544协议打包。

(创建监听)
class Server {
public static void Main() {
TcpListener server = new TcpListener(IPAddress.Parse("127.0.0.1"), 80);

server.Start();
Console.WriteLine("Server has started on 127.0.0.1:80.{0}Waiting for a connection...", Environment.NewLine);

TcpClient client = server.AcceptTcpClient();

Console.WriteLine("A client connected.");
}
}
(接收数据)
TcpClient client = server.AcceptTcpClient();

Console.WriteLine("A client connected.");

NetworkStream stream = client.GetStream();

while(client.Available < 3)
{
// wait for enough bytes to be available
}
//enter to an infinite cycle to be able to handle every change in stream
while (true) {
while (!stream.DataAvailable);

Byte[] bytes = new Byte[client.Available];

stream.Read(bytes, 0, bytes.Length);
}
(打包发送的数据)
if (new System.Text.RegularExpressions.Regex("^GET").IsMatch(data))
{
const string eol = "\r\n"; // HTTP/1.1 defines the sequence CR LF as the end-of-line marker

Byte[] response = Encoding.UTF8.GetBytes("HTTP/1.1 101 Switching Protocols" + eol
+ "Connection: Upgrade" + eol
+ "Upgrade: websocket" + eol
+ "Sec-WebSocket-Accept: " + Convert.ToBase64String(
System.Security.Cryptography.SHA1.Create().ComputeHash(
Encoding.UTF8.GetBytes(
new System.Text.RegularExpressions.Regex("Sec-WebSocket-Key: (.*)").Match(data).Groups[1].Value.Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
)
)
) + eol
+ eol);

stream.Write(response, 0, response.Length);
}

客户端:

  • html5的JS库
  • Fleck库
  • websocketsharp库
  • 微软自己的wensocketclient库
  • 自己按照RFC6544协议,打包协议头+socket API库,收发数据

【转】WebSocket初探相关推荐

  1. Spring WebSocket初探2 (Spring WebSocket入门教程)

    2019独角兽企业重金招聘Python工程师标准>>> WebSocket前端准备 SockJS: SockJS 是一个浏览器上运行的 JavaScript 库,如果浏览器不支持 W ...

  2. 【WebSocket初探 】

    众所周知,socket是编写网络通信应用的基本技术,网络数据交换大多直接或间接通过socket进行.对于直接使用socket的client与服务端,一旦连接被建立则均可主动向对方传送数据,而对于使用更 ...

  3. websocket初探

    过去都是使用浏览器端插件(如flash和java applet)与服务器建立套接字通信,这些插件技术曾经广泛应用在网页聊天和网页游戏,html5提供的websocket有取代这些插件的趋势. 在web ...

  4. Bookmarks(三)

    Bookmarks 书签栏 tooltips提示效果,支持点击与经过显示,位置和效果可以自定义 - CSDN博客 疯狂的小萝卜头 - 博客园 [Kettle从零开始]第九弹之Kettle定时任务介绍 ...

  5. c# websocket 心跳重连_初探和实现websocket心跳重连(npm: websocket-heartbeat-js) - 子慕大诗人 - 博客园...

    (event) { heartCheck.reset(); 如上代码,heartCheck 的 reset和start方法主要用来控制心跳的定时. 什么条件下执行心跳: 当onopen也就是连接成功后 ...

  6. 网页实时聊天之PHP如何实现websocket

    网页实时聊天之PHP如何实现websocket 一.总结 一句话总结: 应用 PHP 的 socket 函数库:PHP 的 socket 函数库跟 C 语言的 socket 函数非常类似 PHP 实现 ...

  7. 【CSS3初探之变形与动画】令人惊叹的CSS3

    前言 这个标题比较狗血了,我一直知道CSS3可以做很多事情,但是我昨天看到一个人用CSS3华丽的画了一个太极八卦! 若是这个还可以接受,那么我今天就看见一个人用CSS3画了一个叮当猫!!!我突然就在想 ...

  8. 云原生时代, Kubernetes 多集群架构初探

    为什么我们需要多集群? 近年来,多集群架构已经成为"老生常谈".我们喜欢高可用,喜欢异地多可用区,而多集群架构天生就具备了这样的能力.另一方面我们也希望通过多集群混合云来降低成本, ...

  9. websocket 历史及使用详解

    一.阅前热身 什么是keep-alive 1.keep-alive只是客户端的一种建议 我们打开百度首页,进一步查看header. image_1b2idfp2k4ecu8pagh1mkutf39.p ...

最新文章

  1. Android 使用摄像头拍照
  2. JVM 学习笔记 1. JVM 运行模型
  3. [Win32]一个调试器的实现(四)读取寄存器和内存
  4. 经典|图解Linux内存性能优化核心思想
  5. 15 操作系统第四章 文件管理 文件的物理结构 文件存储空间管理
  6. 营销型成人高考自考百度竞价推广落地页源码 单页织梦模板 带手机版
  7. STM32工作笔记0067---SPI接口原理与配置
  8. C#实现二维码功能,winform 以及 asp.net均可以用
  9. python中集合的元素可以是_python中的集合
  10. idea整个项目乱码解决办法
  11. HTTP405: 错误方法 - 不支持使用的 HTTP 谓词。
  12. js字符串去空格回车换行
  13. pdf加密阅读html,pdf文档加密如何解除
  14. verilog latch
  15. Linux修仙之路——RAID技术
  16. X710网卡接收丢包
  17. 高德地图js API实现多点标记marker,多点marker移除和鼠标滑入标点显示提示框
  18. c语言中缺少参数怎么弄,printf参数不足
  19. Swift5代码添加约束
  20. vue 环信im 接收语音

热门文章

  1. 【Makefile由浅入深完全学习记录5】预定义变量的使用
  2. sql的case when用法
  3. 排序之选择排序:简单选择+堆排序
  4. Asp.net的HTTP请求处理过程
  5. 与大家分享一下2010我的找工作历程!真累啊!不过都已经结束了!
  6. SQL Server 清空或删除所有数据库表中的数据
  7. [Leedcode][JAVA][第470题][Ran7()实现Rand10()]
  8. 安卓开发toolbar设置logo_Android之ToolBar的使用
  9. java 异步socket_java Socket读写异步分离
  10. android activity之间传递对象,Android Activity之间的数据传递