socket 如今也出现在了 javascript 中,浏览器端有 html5 规范的 websocket
来完成客户端信息发送,服务器端则可以在 nodejs 平台上实现对应的服务器信息接收
(原生支持的异步io读取),而另一方面客户端 api 由 w3c 制定,具体的通信协议则由 IETF
指定,目前尚处于草稿阶段,最新的规范也已过期。
客户端发送:
目前只有 chrome 支持 websocket ,通过
var webSocket = new WebSocket('ws://xx.com:8081/');
来创建客户端 socket 对象,而具体通信协议则是采用更早的 draft-ietf-hybi-thewebsocketprotocol-00
。
通过 send 方法来发送 utf-8 编码的文本信息(二进制上尚不支持)。通过 onopen , onmessage 回调来获取服务器端的对应返回状态和数据。
基本原理:
首先是握手阶段(handshake):浏览器发送 http get 请求到对应 xx.com:8081 ,并携带对应协议头 :
注意最后的 (key3) 并不表示一个 http header,而是在头结束后第二行的8个字节为 0x7D 0x24 ....,这8字节不属于 header 部分,由于是 get 请求,也不属于 body部分,造成一般的 web 容器经过层层封装后应用根本读不出来。
服务器端然后设置返回状态码 101 ,并根据 sec-websocket-key1/2 以及最后的 8 个字节,计算出另外一个字符串回来确认(challenge response 为了安全?):
至此,握手完毕,该 http 链接的 tcp 链接保留,以后数据传输直接通过 socket 进行(也即提升为 websocket),不过数据开头以 0x00 开头,以 0xFF 结尾,服务器端也是如此,只不过浏览器端会自动进行数据解包,因而对应用透明。
服务器端接收:
服务器实际上是一个特殊的 web (http)服务器,不同于一般的 http server,应用完全不需要了解 http 底层的 tcp socket,在 websocket 请求时就要适当暴漏承载 http 链接的 tcp socket,所以目前的 servlet 容器例如 tomcat就不行了(不可能从 httpRequest 直接得到它关联的 socket,被 tomcat 屏蔽了,另一个原因是不能读到请求的 raw data 造成 key3 读不到),这才有了 jetty
经过改造后支持 websocket 的 servlet 容器,或者直接手写 websocket 专用服务器
。
nodejs 下实现
nodejs 的 http server 已经支持 websocket 的握手阶段,能够将握手阶段作为事件触发出来,并且读出 key3,一旦到了握手阶段,该 socket 就会暴露出来 :
server.on('upgrade', function(req, socket, upgradeHead) { });
这时应用就可以设置 socket 为 keepalive 一直保持打开状态:
socket.setKeepAlive(true, 0);
接下来就是读取对应的 key1 和 key2 以及 key3,计算需要返回的确认值,以及准备其他必要的信息头(origin,location...)发送到客户端
res = 'HTTP/1.1 101 WebSocket Protocol Handshake\r\n' +
'Upgrade: WebSocket\r\n' +
'Connection: Upgrade\r\n' +
'Sec-WebSocket-Origin: ' + websocket_origin(connection) + '\r\n' +
'Sec-WebSocket-Location: ' + location;
.......
connection._socket.write(res, 'binary');
完成了握手阶段后,客户端会直接通过 socket 发送信息,而服务器也会经过服务器端socket的data 事件来获取客户端信息处理:
socket.on('data', function(data) {
//todo
});
服务器通过 socket 的 write 来向客户端浏览器发送信息,这时也要将数据用 0x00 和 0xff 包裹起来:
Connection.prototype.write = function(data) {
return this.socket.write( '\u0000' + data + '\uffff');
};
问题:
使用 websocket 使得客户端和服务器端都可以重用同一个 tcp 链接,不用频繁建立销毁 http 链接,并且可以避免采用 http 请求冗余的头信息,大幅提高反应速度。但是估计会降低可访问的客户端数,毕竟服务器链接有限,都被早来的客户端占完了:(
Refer:
flash 模拟的 websocket
nodejs 的 websocket 服务器模块
websocket 介绍
客户端html5 api w3c规范
websocket IETF通信协议
如何通过握手建立连接
- 大小: 24.2 KB
- 大小: 7.7 KB
分享到:
相关推荐
在这个特定的案例中,我们将讨论如何使用Java作为客户端,通过Socket连接到使用Node.js构建的服务器进行通信。Socket编程是一种基础的网络通信机制,允许两个应用程序通过网络交换数据。 首先,让我们深入了解一下...
这是因为浏览器实质上也是一个客户端,它可以发起HTTP或HTTPS请求,这里的Socket通信可能是在一个特定的HTTP服务器框架下实现的,如Tomcat或Node.js的http模块。 6. 文件"MyServer": 这个文件名可能代表服务器端...
socket.on("message") { data, ack in if let message = data[0] as? String { print("Received message: \(message)") } } ``` 此外,发送消息给服务器也非常简单: ```swift socket.emit("eventName", ...
在现代网络应用中,JSON(JavaScript Object Notation)已成为数据交换的常用格式,而socket编程则是实现网络通信的基础。本篇文章将深入探讨如何在C++环境中解析JSON数据以及运用socket进行客户端与服务器之间的...
socket.onError = { error in print("WebSocket 错误:", error.localizedDescription) } socket.onClose = { code, reason, clean in print("WebSocket 连接已关闭:", reason) } socket.connect() ``` 2. **...
在C++中,可以使用标准库中的`<sys/socket.h>`和`<netinet/in.h>`等头文件来实现Socket通信。 4. **图片传输**: 图片通常以二进制格式存储,如JPEG、PNG等。在Socket中传输图片时,需要先将图片文件读取为字节流,...
《Node.js in Action》中文版是一本专门针对Node.js技术的实战指南,由业界知名人士“狼叔”推荐,旨在帮助读者深入理解和掌握这一强大的JavaScript后端开发平台。Node.js以其异步、非阻塞I/O模型和高效的性能在Web...
Node.js作为一个高效的JavaScript运行环境,它允许开发者使用JavaScript进行服务器端编程,而Socket.IO则提供了实时双向通信的能力,使得构建实时应用如聊天室变得简单。 首先,我们需要安装必要的依赖。在命令行中...
实例: <head> <script type="text/... } // Setup our socket in the div with the id="socket" socket.setup('#socket'); </script></body>}} 原文地址:http://code.google.com/p/jsocket/wiki/SimpleExample
这是一个基于JavaScript技术栈的实时聊天应用项目,使用了React作为前端框架,Node.js作为后端服务器,Socket.io作为实时通信库,并将数据存储在MongoDB数据库中。让我们深入探讨这个项目涉及的技术点。 1. **React...
即时聊天应用描述在Node js和socket.io的帮助下使用HTML和javascript制作的实时聊天应用程序预习运行程序$ git clone https://github.com/zaidajani/live-chat-app.git# Copy the project$ cd live-chat-app# Get ...
Socket.IO Redis发射器 @socket.io/redis-emitter软件包使您可以轻松地与另一个Node.js进程(服务器端)中的一组Socket.IO服务器进行通信。 发射器还提供其他编程语言版本: Java: : Python: : ...
在本文中,我们将深入探讨如何使用Node.js、Express和Socket.io构建一个实时聊天应用程序,正如“socket-chat”项目所示。这个应用将展示如何利用这些技术实现实时通信,特别是对于在线聊天室或协作工具等场景。 ...
Vue.js是一个流行的JavaScript框架,用于构建用户界面,而Socket.IO是一个用于实时、双向和基于事件的通信的库,允许服务器和客户端之间直接交互。Vue.js结合Socket.IO可以用于构建各种实时交互的应用,比如在线聊天...
Socket是网络编程中的基本概念,它是进程间通信的一种方式,特别是在分布式系统中,用于实现不同计算机之间的通信。本文将深入探讨Socket的使用,基于提供的资源,我们主要关注以下几个方面: 1. **Socket基础** ...
socket 地址结构 1. IPv4 的Socket 地址结构(定长) Struct in_addr{ In_addr_t s_addr; // 32 位IP 地址,网络字节序 } Struct sockaddr_in{ Uint8_t sin_len;//IPv4 为固定的16 字节长度 Sa_family_t sin_...
在本文中,我们将深入探讨“flutter-socket.io-server”,这是一个专门为Flutter应用程序设计的基于JavaScript的快速基础服务器,它利用了Socket.IO库的强大功能。 首先,让我们了解一下Flutter。Flutter是由Google...