怎么使用 socket.io websocket连接 WebSocket 服务

软件指南针:专注于软件传播与分享
当前位置: >>
Tomcat WebSocket指南
来源:原创
1545次浏览
? 本文主要介绍软件『』的相关内容:Tomcat WebSocket指南。
&&&其下列版本/分支可以参考本文:
全部版本/分支
Tomcat提供对在定义的WebSocket的支持。
应用程序开发
Tomcat实现在中定义的Java WebSocket 1.0 API。
有几个示例应用程序,演示了如何使用WebSocket API。你需要看看客户端的和服务器端的。
虽然WebSocket实现可以与任何HTTP连接器一起工作,但是不推荐WebSocket和BIO HTTP连接器配合使用。因为WebSocket的典型使用并不适合HTTP BIO连接器,HTTP BIO 连接器要求为每个连接分配一个线程,而不管是否有空闲的连接。
据报告(),Linux会花费大量时间来报告丢掉的连接。当以BIO HTTP连接器使用WebSocket时,这可能会导致该时段内写入出现阻塞。这似乎是不可取的。通过使用内核网络参数/proc/sys/net/ipv4/tcp_retries2,可以减少因连接丢失所花费的报告时间。此外,他们使用了非阻塞IO,可以让Tomcat实现自己的超时机制从而处理这些情况,你也可以使用其他的HTTP连接器。
Tomcat WebSocket具体的配置
Tomcat为WebSocket提供了一些Tomcat特定的配置选项。随着时间的推移,预计这些将被收录到WebSocket规范中。当在阻塞模式下发送WebSocket信息时,使用的写入超时时间默认为20000毫秒(20秒)。你可以通过在用户属性集合中设置org.apache.tomcat.websocket.BLOCKING_SEND_TIMEOUT来进行变更,用户属性集合被附加到WebSocket 会话中。
分配给该属性的值应该是一个Long类型的数据,并以毫秒为单位来表示使用的超时时间。如果不限制超时时间,请使用-1。
如果应用程序没有为输入的二进制信息定义一个MessageHandler.Partial,任何输入的二进制信息都应该被缓冲,这样,整个消息可以在一次调用中传递给为二进制信息注册的MessageHandler.Whole。二进制信息默认的缓存大小为8192字节(8KB)。你也可以通过为servlet context的初始化参数org.apache.tomcat.websocket.binaryBufferSize设置期望的以字节为单位的值来更改它。
Java WebSocket 规范 1.0不允许在第一个终端已经开始一个WebSocket握手之后进行规划部署。在默认情况下,Tomcat继续允许额外的规划部署。该行为可以通过servlet context的初始化参数org.apache.tomcat.websocket.noAddAfterHandshake来控制。
你可以通过设置系统属性org.apache.tomcat.websocket.STRICT_SPEC_COMPLIANCE为true来修改默认值,但是servlet&context中的任何显示设置将始终被优先采用。
Java WebSocket 1.0 规范要求在一个不同的线程上执行到发起写入的线程的异步写入回调。由于容器线程池不是通过Servlet API被暴露,因此WebSocket实现必须提供自己的线程池。该线程池可以通过下列servlet context初始化参数被控制:
org.apache.tomcat.websocket.executorCoreSize: executor线程池的核心大小。如果不设置,则默认为0。
org.apache.tomcat.websocket.executorMaxSize:executor线程池所允许的最大值。如果不设置,则默认为200。
org.apache.tomcat.websocket.executorKeepAliveTimeSeconds:executor线程池中空闲进程所保留的最大时间。如果未指定,则默认为60秒。
当使用WebSocket客户端连接到服务器端时,你可以通过javax.websocket.ClientEndpointConfig提供的userProperties来控制建立连接时IO操作的超时时间。该属性为org.apache.tomcat.websocket.IO_TIMEOUT_MS&,它是一个表示超时时间的、单位为毫秒的字符串(String)。默认值为5000(5秒)。
当使用WebSocket客户端连接到安全服务器终端,你可以使用javax.websocket.ClientEndpointConfig提供的userProperties来控制客户端SSL的配置。可以支持下列用户属性:
org.apache.tomcat.websocket.SSL_CONTEXT
org.apache.tomcat.websocket.SSL_PROTOCOLS
org.apache.tomcat.websocket.SSL_TRUSTSTORE
org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD
默认的信任密码为changeit.
如果设置了org.apache.tomcat.websocket.SSL_CONTEXT&属性,那么org.apache.tomcat.websocket.SSL_TRUSTSTORE和org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD&属性将会被忽略。
作者:(),转载请保留出处!
&2013 软件指南针. All rights reserved.
12 queries in 0.012 seconds.html 5 websocket(C#服务器) - dolphinX - 推酷
html 5 websocket(C#服务器) - dolphinX
在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websocket之前的实现方式可以看看
,有简单提到,同时也说了websocket基本概念)等方式做一个山寨版的web聊天室。
什么是websocket
&WebSocket 协议是html5引入的一种新的协议,其目的在于实现了浏览器与服务器全双工通信。看了上面链接的同学肯定对过去怎么低效率高消耗(轮询或comet)的做此事已经有所了解了,而在websocket API,浏览器和服务器只需要要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。同时这么做有两个好处
1.通信传输字节减少:比起以前使用http传输数据,websocket传输的额外信息很少,据百度说只有2k
2.服务器可以主动向客户端推送消息,而不用客户端去查询
关于概念和好处,网上到处都是,不再赘述,简单看看其原理,然后动手写一个web版聊天室吧
&除了TCP连接的三次握手,websocket协议中客户端与服务器想建立连接需要一次额外的握手动作,在最新版的协议中是这个样子的
客户端向服务器发送请求
GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: 127.0.0.1:8080
Pragma: no-cache
Cache-Control: no-cache
Sec-WebSocket-Key: OtZtd55qBhJF2XLNDRgUMg==
Sec-WebSocket-Version: 13
Sec-WebSocket-Extensions: x-webkit-deflate-frame
User-Agent: Mozilla/5.0 (M Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
服务器给出响应
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: xsOSgr30aKL2GNZKNHKmeT1qYjA=
&在请求中的“Sec-WebSocket-Key”是随机的,服务器端会用这些数据来构造出一个SHA-1的信息摘要。把“Sec-WebSocket-Key”加上一个魔幻字符串“258EAFA5-E914-47DA-95CA-C5AB0DC85B11”。使用 SHA-1 加密,之后进行 BASE-64编码,将结果做为 “Sec-WebSocket-Accept” 头的值,返回给客户端(来自
websocket API
经过握手之后浏览器与服务器建立连接,两者就可以互相通信了。websocket的API真心很简单,看看
enum BinaryType { &blob&, &arraybuffer& };
[Constructor(DOMString url, optional (DOMString or DOMString[]) protocols)]
interface WebSocket : EventTarget {
readonly attribute DOMS
// 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 readyS
readonly attribute unsigned long bufferedA
// networking
attribute EventH
attribute EventH
attribute EventH
readonly attribute DOMS
readonly attribute DOMS
void close([Clamp] optional unsigned short code, optional DOMString reason);
// messaging
attribute EventH
attribute BinaryType binaryT
void send(DOMString data);
void send(Blob data);
void send(ArrayBuffer data);
void send(ArrayBufferView data);
创建websocket
ws=new WebSocket(address); //ws://127.0.0.1:8080
调用其构造函数,传入地址,就可以创建一个websocket了,值得注意的是地址协议得是ws/wss
关闭socket
ws.close();
调用webservice实例的close()方法就可以关闭webservice,当然也可以传入一个code和string说明为什么关了
几个回调函数句柄
由于其异步执行,回调函数自然少不了,有四个重要的
onopen:连接创建后调用
onmessage:接收到服务器消息后调用
onerror:出错时调用
onclose:关闭连接的时候调用
看名字就知道是干什么的了,每个回调函数都会传入一个Event对象,可以通过event.data访问消息
我们可以在创建socket成功后为其回调函数赋值
ws=new WebSocket(address);
ws.onopen=function(e){
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML=&Server & connection open.&;
msgContainer.appendChild(msg);
ws.send('{&'+document.getElementById('name').value+'&}');
&也可以通过事件绑定的方式
ws=new WebSocket(address);
ws.addEventListener('open',function(e){
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML=&Server & connection open.&;
msgContainer.appendChild(msg);
ws.send('{&'+document.getElementById('name').value+'&}');
&客户端实现
其实客户端的实现比较简单,除了websocket相关的几句就是一些自动focus、回车键事件处理、消息框自动定位到底部等简单功能,不一一说明了
1 &!DOCTYPE html&
&title&Web Socket Client&/title&
6 &body style=&padding:10&&
&h1&Web Socket Chating Room&/h1&
&div style=&margin:5px 0&&
&div&&input id=&address& type=&text& value=&ws://127.0.0.1:8080& style=&width:400&/&&/div&
&div style=&margin:5px 0&&
&div&&input id=&name& type=&text& value=&Byron& style=&width:400&/&&/div&
&button id=&connect& onclick=&connect();&&connect server&/button& &&
&button id=&disconnect& onclick=&quit();&&disconnect&/button&&&
&button id=&clear& onclick=&clearMsg();&&clear&/button&
&h5 style=&margin:4px 0&&Message:&/h5&
&div id=&message& style=&border:solid 1px #333; padding:4 width:400 overflow:
background-color:#404040; height:300 margin-bottom:8 font-size:14&&
&input id=&text& type=&text& onkeypress=&enter(event);& style=&width:340px&/& &&
&button id=&send& onclick=&send();&&send&/button&
&script type=&text/javascript&&
var name=document.getElementById('name').
var msgContainer=document.getElementById('message');
var text=document.getElementById('text');
function connect () {
var address=document.getElementById('address').
ws=new WebSocket(address);
ws.onopen=function(e){
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML=&Server & connection open.&;
msgContainer.appendChild(msg);
ws.send('{&'+document.getElementById('name').value+'&}');
ws.onmessage=function(e){
var msg=document.createElement('div');
msg.style.color='#fff';
msg.innerHTML=e.
msgContainer.appendChild(msg);
ws.onerror=function(e){
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML='Server & '+e.
msgContainer.appendChild(msg);
ws.onclose=function(e){
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML=&Server & connection closed by server.&;
msgContainer.appendChild(msg);
text.focus();
function quit(){
ws.close();
var msg=document.createElement('div');
msg.style.color='#0f0';
msg.innerHTML='Server & connection closed.';
msgContainer.appendChild(msg);
function send(){
ws.send(text.value);
setTimeout(function(){
msgContainer.scrollTop=msgContainer.getBoundingClientRect().
text.value='';
text.focus();
function clearMsg(){
msgContainer.innerHTML=&&;
function enter(event){
if(event.keyCode==13){
95 &/body&
96 &/html&
服务器支持
&其实websocket的服务器实现网上可以找到很多了,向维基百科中列出的
&(版本7开始支持websocket)
Kaazing -&
&(7.0.26支持websocket)
WebLogic -&
&(12.1.2 开始支持)
node.js -&
node.js -&
mojolicious -&
&但是我希望加入一些自己特定的处理,比如用户名识别啊、广播啊什么的,所以自己实现了一个简单的C#版本
websocket 聊天室C#服务器实现
我上篇博客
中介绍了怎么实现一个简单的C#广播服务器,在这上面扩展两个部分就能作为websocket服务器了
1.wecsocket握手处理
&当服务器收到浏览器握手请求后,首先需要识别握手信息,我简单粗暴的使用了包含字符串处理,当然加入了是否握过手的判断
client.BeginReceive (buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback (Recieve), client);
string msg = Encoding.UTF8.GetString (buffer, 0, length);
if (!clientPool [client].IsHandShaked && msg.Contains (&Sec-WebSocket-Key&)) {
client.Send (PackageHandShakeData (buffer, length));
clientPool [client].IsHandShaked = true;
识别成功后就可以生成服务器响应发送给客户端了
/// &summary&
/// 打包服务器握手数据
/// &/summary&
/// &returns&The hand shake data.&/returns&
/// &param name=&handShakeBytes&&Hand shake bytes.&/param&
/// &param name=&length&&Length.&/param&
private byte[] PackageHandShakeData (byte[] handShakeBytes, int length)
string handShakeText = Encoding.UTF8.GetString (handShakeBytes, 0, length);
string key = string.E
Regex reg = new Regex (@&Sec\-WebSocket\-Key:(.*?)\r\n&);
Match m = reg.Match (handShakeText);
if (m.Value != &&) {
key = Regex.Replace (m.Value, @&Sec\-WebSocket\-Key:(.*?)\r\n&, &$1&).Trim ();
byte[] secKeyBytes = SHA1.Create ().ComputeHash (
Encoding.ASCII.GetBytes (key + &258EAFA5-E914-47DA-95CA-C5AB0DC85B11&));
string secKey = Convert.ToBase64String (secKeyBytes);
var responseBuilder = new StringBuilder ();
responseBuilder.Append (&HTTP/1.1 101 Switching Protocols& + &\r\n&);
responseBuilder.Append (&Upgrade: websocket& + &\r\n&);
responseBuilder.Append (&Connection: Upgrade& + &\r\n&);
responseBuilder.Append (&Sec-WebSocket-Accept: & + secKey + &\r\n\r\n&);
return Encoding.UTF8.GetBytes (responseBuilder.ToString ());
2.解析浏览器消息和处理发送给浏览器的消息
&websocket中数据并不完全是消息本身,我们需要做一些处理
/// &summary&
/// 解析客户端发送来的数据
/// &/summary&
/// &returns&The data.&/returns&
/// &param name=&recBytes&&Rec bytes.&/param&
/// &param name=&length&&Length.&/param&
private string AnalyzeClientData (byte[] recBytes, int length)
if (length & 2) {
return string.E
bool fin = (recBytes [0] & 0x80) == 0x80; // 1bit,1表示最后一帧
if (!fin) {
return string.E// 超过一帧暂不处理
bool mask_flag = (recBytes [1] & 0x80) == 0x80; // 是否包含掩码
if (!mask_flag) {
return string.E// 不包含掩码的暂不处理
int payload_len = recBytes [1] & 0x7F; // 数据长度
byte[] masks = new byte[4];
byte[] payload_
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 & i++) {
payload_data [i] = recBytes [i + 14];
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_ i++) {
payload_data [i] = (byte)(payload_data [i] ^ masks [i % 4]);
return Encoding.UTF8.GetString (payload_data);
解析客户端发送来的数据
/// &summary&
/// 把客户端消息打包处理(拼接上谁什么时候发的什么消息)
/// &/summary&
/// &returns&The data.&/returns&
/// &param name=&message&&Message.&/param&
private byte[] PackageServerData (SocketMessage sm)
StringBuilder msg = new StringBuilder ();
if (!sm.isLoginMessage) { //消息是login信息
msg.AppendFormat (&{0} @ {1}:\r\n
&, sm.Client.Name, sm.Time.ToShortTimeString ());
msg.Append (sm.Message);
} else { //处理普通消息
msg.AppendFormat (&{0} login @ {1}&, sm.Client.Name, sm.Time.ToShortTimeString ());
byte[] content = null;
byte[] temp = Encoding.UTF8.GetBytes (msg.ToString ());
if (temp.Length & 126) {
content = new byte[temp.Length + 2];
content [0] = 0x81;
content [1] = (byte)temp.L
Array.Copy (temp, 0, content, 2, temp.Length);
} else if (temp.Length & 0xFFFF) {
content = new byte[temp.Length + 4];
content [0] = 0x81;
content [1] = 126;
content [2] = (byte)(temp.Length & 0xFF);
content [3] = (byte)(temp.Length && 8 & 0xFF);
Array.Copy (temp, 0, content, 4, temp.Length);
// 暂不处理超长内容
把发送给客户端消息打包处理
如果看不懂我在写什么,并且对C#版websocket感兴趣的同学需要看一下我上一篇博客了
有图有真相
看看我们写的聊天室运行效果吧
&客户端——Byron
客户端——Casper
&源代码我已经上传到了我的
,对github不感冒的同学可以直接点击这里下载,有兴趣的同学可以下载看看,因为我在Mac+mono+Xamarin Studio上开发的(忽然感觉自己好极品在Mac上用C#。。。),所以代码编码和Windows可能会有些差距,改成Windows兼容的应该就可以直接运行了,不过没在Window下跑过,如果有错误还请大家多多指正。
已发表评论数()
&&登&&&录&&
已收藏到推刊!
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见html5相关信息
?相关html5文章推荐
热门html5文章推荐
广告赞助商
html5文章阅读排
带你认识HTML5中的WebSocket
摘要:认识 HTML5 的 WebSocket 在 HTML5 规范中,我最喜欢的Web技术就是正迅速变得流行的 WebSocket API。WebSocket 提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术。这个新的API提供了一个方法,从客户端使用简单的语法有效地推动消息到服务器。
&认识 HTML5 的 WebSocket
在 HTML5 规范中,我最喜欢的Web技术就是正迅速变得流行的 WebSocket API。WebSocket
提供了一个受欢迎的技术,以替代我们过去几年一直在用的Ajax技术。这个新的API提供了一个方法,从客户端使用简单的语法有效地推动消息到。让我们看一看
HTML5 的 WebSocket API:它可用于客户端、端。而且有一个优秀的第三方API,名为Socket.IO。
一、HTML5 中的 WebSocket API 是个什么东东?
API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox
4、Chrome 4、Opera 10.70以及Safari 5等浏览器的支持。
API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。
Ajax技术很聪明的一点是没有设计要使用的方式。WebSocket为指定目标创建,用于双向推送消息。
二、HTML5 中的 WebSocket API 的用法
只专注于客户端的API,因为每个服务器端语言有自己的API。下面的代码片段是打开一个连接,为连接创建事件监听器,断开连接,消息时间,发送消息返回到服务器,关闭连接。
// 创建一个Socket实例
var socket = new
WebSocket('ws://localhost:8080');
// 打开Socket
socket.onopen =
function(event){
// 发送一个初始化消息
socket.send('I am the client and I\'m
listening!');
// 监听消息
socket.onmessage =
function(event){
console.log('Client received a message',event);
监听Socket的关闭
socket.onclose = function(event){
console.log('Client notified
socket has closed',event);
// 关闭Socket....
//socket.close()
让我们来看看上面的初始化片段。参数为URL,ws表示WebSocket协议。onopen、onclose和onmessage方法把事件连接到Socket实例上。每个方法都提供了一个事件,以表示Socket的状态。
onmessage事件提供了一个data属性,它可以包含消息的Body部分。消息的Body部分必须是一个字符串,可以进行序列化/反序列化操作,以便传递更多的数据。
WebSocket的语法非常简单,使用WebSockets是难以置信的容易&&除非客户端不支持WebSocket。IE浏览器目前不支持WebSocket通信。如果你的客户端不支持WebSocket通信,下面有几个后备方案供你使用:
Flash技术 && Flash可以提供一个简单的替换。
使用Flash最明显的缺点是并非所有客户端都安装了Flash,而且某些客户端,如iPhone/iPad,不支持Flash。
AJAX Long-Polling技术 &&
用AJAX的long-polling来模拟WebSocket在业界已经有一段时间了。它是一个可行的技术,但它不能优化发送的信息。也就是说,它是一个解决方案,但不是最佳的技术方案。
由于目前的IE等浏览器不支持WebSocket,要提供WebSocket的事件处理、返回传输、在服务器端使用一个统一的API,那么该怎么办呢?幸运的是,Guillermo
Rauch创建了一个Socket.IO技术。
三、带Socket.IO的WebSocket
Socket.IO是Guillermo Rauch创建的WebSocket API,Guillermo
Rauch是LearnBoost公司的首席技术官以及LearnBoost实验室的首席科学家。Socket.IO使用检测功能来判断是否建立WebSocket连接,或者是AJAX
long-polling连接,或Flash等。可快速创建实时的应用程序。Socket.IO还提供了一个NodeJS API,它看起来非常像客户端API。
(原文出处:吾吾织梦)
------分隔线----------------------------
下一篇:没有了
◎ 广告赞助
◎ 阅读说明READ EXPLANATION
推荐使用第三方专业下载工具下载本站软件,使用 WinRAR v3.10 以上版本解压本站软件。
本站空间有限.资源到网盘下载.谢谢&& 赞助本站(广告),联系站长QQ&&
为加快源码更新本站源码未全部调试.所以有关源码问题请到交流,讨论,
如须购买金币(升级VIP)&本站解压密码
下载本站资源,如果服务器暂不能下载请过一段时间重试!
如果遇到什么问题,请到本站论坛去咨寻,我们将在那里提供更多 、更好的资源!
本站提供的一些商业软件是供学习研究之用,如用于商业用途,请购买正版。后使用快捷导航没有帐号?
Nodejs实现websocket的4种方式
查看: 17754|
评论: 0|原作者: 张丹(Conan)|来自:
摘要: WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。在WebSocket API中,浏览器和服务器只需要要做一个握手(handshaking)的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就 ...
将介绍如何利Javascript做为服务端脚本,通过Nodejs框架web开发。Nodejs框架是基于V8的引擎,是目前速度最快的
Javascript引擎。chrome浏览器就基于V8,同时打开20-30个网页都很流畅。Nodejs标准的web开发框架Express,可以帮
助我们迅速建立web站点,比起PHP的开发效率更高,而且学习曲线更低。非常适合小型网站,个性化网站,我们自己的Geek网站!!
张丹(Conan), 程序员Java,R,PHP,Javascript
weibo:@Conan_Z
转载请注明出处:
前言WebSocket是HTML5开始提供的一种浏览器与服务器间进行全双工通讯的网络技术。在WebSocket
API中,浏览器和服务器只需要要做一个握手(handshaking)的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据
互相传送。WebSocket是一个通信的协议,分为服务器和客户端。服务器放在后台,保持与客户端的长连接,完成双方通信的任务。客户端一般都是实现在支持
HTML5浏览器核心中,通过提供JavascriptAPI使用网页可以建立websocket连接。Java实现的案例,请参考:今天让我们来看看在nodejs中,如何实现websocket的通信。目录
为什么用Nodejs
node-websocket-server:测试失败
node-websocket:测试成功
faye-websocket-node: 测试成功
socket.io: 测试成功
1. 为什么用Nodejs?1. 事件驱动,通过闭包很容易实现客户端的生命活期。
2. 不用担心多线程,锁,并行计算的问题
3. V8引擎速度非常快
4. 对于游戏来说,写一遍游戏逻辑代码,前端后端通用。当然Nodejs也有一些缺点:
1. nodejs更新很快,可能会出现版本联兼容
2. nodejs还不算成熟,还没有大制作。
3. nodejs不像其他的服务器,对于不同的连接,不支持进程和线程操作。在权衡Nodejs给我们带来无限畅快的开发的同时,要考虑到他的不成熟,特别是对于“长连接”的网络通信应用。下面我将分别,测试一下网上几种Nodejs实现websocket的框架。我的系统环境
win7 64bit
Nodejs:v0.10.5
Npm:1.2.19
~ D:\workspace\javascript&node -v
~ D:\workspace\javascript&npm -v
1.2.192. node-websocket-server: 测试失败github: /miksago/node-websocket-server
node-websocket-server:是基于nodejs底层API实现的,可能产生不兼容的机率是90-100%,现在已经不建议再使用了。我
查了代码库,发现已经有两年没有更新了,所以还在准备用node-websocket-server框架的同学,要特别小心了。我也做了一个实验,一直会报错,贴一下实验代码。
~ D:\workspace\javascript&mkdir nodejs-websocket-server
~ D:\workspace\javascript&cd nodejs-websocket-server
~ D:\workspace\javascript\nodejs-websocket-server&npm install websocket-server
npm http GET https://registry.npmjs.org/websocket-server
npm http 304 https://registry.npmjs.org/websocket-server
npm http GET https://registry.npmjs.org/websocket-server/-/websocket-server-1.4.04.tgz
npm http 200 https://registry.npmjs.org/websocket-server/-/websocket-server-1.4.04.tgz
websocket-server@1.4.04 node_modules\websocket-server
~ vi app.js
var conns = new Array();
var ws = require("websocket-server");
var server = ws.createServer();
server.addListener("connection", function(connection){
console.log("Connection request on Websocket-Server");
conns.push(connection);
connection.addListener('message',function(msg){
console.log(msg);
for(var i=0; i&conns. i++){
if(conns[i]!=connection){
conns[i].send(msg);
server.listen(3001);
客户端连接:
&div id="output"&&/div&
function checkBrowser(){
if (window.WebSocket){
log("This browser supports WebSocket!");
log("This browser does not support WebSocket.");
function setup(){
var wsServer = 'ws://localhost:3001';
var ws = new WebSocket(wsServer);
ws.onopen = function (e) {
log("Connected to WebSocket server.",e);
sendMessage("Conan");
ws.onclose = function (e) {
log("Disconnected",e);
ws.onmessage = function(e) {
log("RECEIVED: " + e.data, e);
ws.close();
ws.onerror = function (e) {
log('Error occured: ' + e.data,e);
var sendMessage = function(msg){
ws.send(msg);
log("SEND : "+ msg);
function log(s,e) {
var output = document.getElementById("output");
var p = document.createElement("p");
p.style.wordWrap = "break-word";
p.style.padding="10px";
p.style.background="#eee";
p.textContent = "LOG : "+s;
output.appendChild(p);
console.log("LOG : "+s, e);
checkBrowser();
错误提示:
查了一下原因,node-websocket-server,不支持websocket的draft-10,而chrome
14+浏览器,只支持draft-10的websocket,这样chrome基本都不能用了。我的chrome版本是28.0.1500.95。所以,
大家就换个思路吧!3. WebSocket-Node: 测试成功github: /Worlize/WebSocket-Node
WebSocket-Node,是一个简单的库,不仅支持draft-10,还有之前的各种版本。服务器端配置
~ D:\workspace\javascript&mkdir nodejs-websocket
~ D:\workspace\javascript&cd nodejs-websocket
D:\workspace\javascript\nodejs-websocket&npm install websocket
npm http GET https://registry.npmjs.org/websocket
npm http 304 https://registry.npmjs.org/websocket
& websocket@1.0.8 install D:\workspace\javascript\nodejs-websocket\node_modules\websocket
& node install.js
[websocket v1.0.8] Attempting to compile native extensions.
[websocket v1.0.8]
Native code compile failed!!
Please note that this module DOES NOT REQUIRE the native components
and will still work without them, though not quite as efficiently.
On Windows, native extensions require Visual Studio and Python.
On Unix, native extensions require Python, make and a C++ compiler.
Start npm with --websocket:verbose to show compilation output (if any).
websocket@1.0.8 node_modules\websocket
上面提示有错误,我本机已经装了Visual Studio和Python,看来有些模块本地编译不成功了。增加app.js
~ vi app.js
// http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
"use strict";
// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-chat';
// Port where we'll run the websocket server
var webSocketsServerPort = 3001;
// websocket and http servers
var webSocketServer = require('websocket').
var http = require('http');
* Global variables
// latest 100 messages
var history = [ ];
// list of currently connected clients (users)
var clients = [ ];
* Helper function for escaping input strings
function htmlEntities(str) {
return String(str).replace(/&/g, '&').replace(//g, '&').replace(/"/g, '"');
// Array with some colors
var colors = [ 'red', 'green', 'blue', 'magenta', 'purple', 'plum', 'orange' ];
// ... in random order
colors.sort(function(a,b) { return Math.random() & 0.5; } );
* HTTP server
var server = http.createServer(function(request, response) {
// Not important for us. We're writing WebSocket server, not HTTP server
server.listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
* WebSocket server
var wsServer = new webSocketServer({
// WebSocket server is tied to a HTTP server. WebSocket request is just
// an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
httpServer: server
// This callback function is called every time someone
// tries to connect to the WebSocket server
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
// accept connection - you should check 'request.origin' to make sure that
// client is connecting from your website
// (http://en.wikipedia.org/wiki/Same_origin_policy)
var connection = request.accept(null, request.origin);
// we need to know client index to remove them on 'close' event
var index = clients.push(connection) - 1;
var userName =
var userColor =
console.log((new Date()) + ' Connection accepted.');
// send back chat history
if (history.length & 0) {
connection.sendUTF(JSON.stringify( { type: 'history', data: history} ));
// user sent some message
connection.on('message', function(message) {
if (message.type === 'utf8') { // accept only text
if (userName === false) { // first message sent by user is their name
// remember user name
userName = htmlEntities(message.utf8Data);
// get random color and send it back to the user
userColor = colors.shift();
connection.sendUTF(JSON.stringify({ type:'color', data: userColor }));
console.log((new Date()) + ' User is known as: ' + userName
+ ' with ' + userColor + ' color.');
} else { // log and broadcast the message
console.log((new Date()) + ' Received Message from '
+ userName + ': ' + message.utf8Data);
// we want to keep history of all sent messages
var obj = {
time: (new Date()).getTime(),
text: htmlEntities(message.utf8Data),
author: userName,
color: userColor
history.push(obj);
history = history.slice(-100);
// broadcast message to all connected clients
var json = JSON.stringify({ type:'message', data: obj });
for (var i=0; i & clients. i++) {
clients[i].sendUTF(json);
// user disconnected
connection.on('close', function(connection) {
if (userName !== false && userColor !== false) {
console.log((new Date()) + " Peer "
+ connection.remoteAddress + " disconnected.");
// remove user from the list of connected clients
clients.splice(index, 1);
// push back user's color to be reused by another user
colors.push(userColor);
启动服务器
~ D:\workspace\javascript\nodejs-websocket&node app.js
Warning: Native modules not compiled.
XOR performance will be degraded.
Warning: Native modules not compiled.
UTF-8 validation disabled.
Wed Aug 21 :48 GMT+0800 (中国标准时间) Server is listening on port 3001
Wed Aug 21 :53 GMT+0800 (中国标准时间) Connection from origin null.
Wed Aug 21 :53 GMT+0800 (中国标准时间) Connection accepted.
Wed Aug 21 :53 GMT+0800 (中国标准时间) User is known as: Conan with red color.
Wed Aug 21 :53 GMT+0800 (中国标准时间) Peer undefined disconnected.
我们看到XOR 和UTF-8 validation 两个模块是被禁止的,不过不影响测试。客户端,还是使用一样的。另外,WebSocket-Node还提供C/S模式的交互,可以不使用浏览器服务端代码
~ vi app2.js
#!/usr/bin/env node
var WebSocketServer = require('websocket').
var http = require('http');
var server = http.createServer(function(request, response) {
console.log((new Date()) + ' Received request for ' + request.url);
response.writeHead(404);
response.end();
server.listen(3001, function() {
console.log((new Date()) + ' Server is listening on port 3001');
wsServer = new WebSocketServer({
httpServer: server,
// You should not use autoAcceptConnections for production
// applications, as it defeats all standard cross-origin protection
// facilities built into the protocol and the browser.
You should
// *always* verify the connection's origin and decide whether or not
// to accept it.
autoAcceptConnections: false
function originIsAllowed(origin) {
// put logic here to detect whether the specified origin is allowed.
wsServer.on('request', function(request) {
if (!originIsAllowed(request.origin)) {
// Make sure we only accept requests from an allowed origin
request.reject();
console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
var connection = request.accept('echo-protocol', request.origin);
console.log((new Date()) + ' Connection accepted.');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log('Received Message: ' + message.utf8Data);
connection.sendUTF(message.utf8Data);
else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
connection.on('close', function(reasonCode, description) {
console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
客户端代码
~ vi client.js
#!/usr/bin/env node
var WebSocketClient = require('websocket').
var client = new WebSocketClient();
client.on('connectFailed', function(error) {
console.log('Connect Error: ' + error.toString());
client.on('connect', function(connection) {
console.log('WebSocket client connected');
connection.on('error', function(error) {
console.log("Connection Error: " + error.toString());
connection.on('close', function() {
console.log('echo-protocol Connection Closed');
connection.on('message', function(message) {
if (message.type === 'utf8') {
console.log("Received: '" + message.utf8Data + "'");
function sendNumber() {
if (connection.connected) {
var number = Math.round(Math.random() * 0xFFFFFF);
connection.sendUTF(number.toString());
setTimeout(sendNumber, 1000);
sendNumber();
client.connect('ws://localhost:3001/', 'echo-protocol');
程序启动:
~ D:\workspace\javascript\nodejs-websocket&node app2.js
~ D:\workspace\javascript\nodejs-websocket&node client.js
测试成功!!4. faye-websocket-node: 测试成功github: /faye/faye-websocket-node
faye-websocket-node,是扩展faye项目而开发的websocket的一个实现。服务器端配置
~ D:\workspace\javascript&mkdir nodejs-faye-websocket
~ D:\workspace\javascript&cd nodejs-faye-websocket
~ D:\workspace\javascript\nodejs-faye-websocket&npm install faye-websocket
npm http GET https://registry.npmjs.org/faye-websocket
npm http 304 https://registry.npmjs.org/faye-websocket
npm http GET https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.6.1.tgz
npm http 200 https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.6.1.tgz
npm http GET https://registry.npmjs.org/websocket-driver
npm http 200 https://registry.npmjs.org/websocket-driver
npm http GET https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.2.2.tgz
npm http 200 https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.2.2.tgz
faye-websocket@0.6.1 node_modules\faye-websocket
└── websocket-driver@0.2.2
~ vi app.js
var WebSocket = require('faye-websocket'),
= require('http');
var server = http.createServer();
server.on('upgrade', function(request, socket, body) {
if (WebSocket.isWebSocket(request)) {
var ws = new WebSocket(request, socket, body);
ws.on('message', function(event) {
ws.send(event.data);
ws.on('close', function(event) {
console.log('close', event.code, event.reason);
server.listen(3001);
~ D:\workspace\javascript\nodejs-faye-websocket&node app.js
用网页客户端访问:测试成功,非常简单!!而且,没有依赖其他的库!!5. socket.io: 测试成功github: /LearnBoost/socket.io环境配置
~ D:\workspace\javascript&express -e nodejs-socketio
~ D:\workspace\javascript&cd nodejs-socketio && npm install
~ D:\workspace\javascript\nodejs-socketio&npm install socket.io
修改app.js配置文件
~ vi app.js
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
server.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/client/index.html');
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
增加客户端文件,注意这个的index.html要根据app.js指定的位置”res.sendfile(__dirname + ‘/client/index.html’);”
~ mkdir client
~ vi /client/index.html
&!DOCTYPE html&
&title&socket.io&/title&
&link rel='stylesheet' href='/stylesheets/style.css' /&
&h1&socket.io&/h1&
&p&Welcome to socket.io&/p&
&script src="/socket.io/socket.io.js"&&/script&
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
启动服务器
~ D:\workspace\javascript\nodejs-socketio&node app.js
- socket.io started
打开浏览器: http://localhost
查看服务器日志:
debug - served static content /socket.io.js
debug - client authorized
- handshake authorized ZR-xQhsKCCqM03TRHW4b
debug - setting request GET /socket.io/1/websocket/ZR-xQhsKCCqM03TRHW4b
debug - set heartbeat interval for client ZR-xQhsKCCqM03TRHW4b
debug - client authorized for
debug - websocket writing 1::
debug - websocket writing 5:::{"name":"news","args":[{"hello":"world"}]}
{ my: 'data' }
debug - emitting heartbeat for client ZR-xQhsKCCqM03TRHW4b
debug - websocket writing 2::
debug - set heartbeat timeout for client ZR-xQhsKCCqM03TRHW4b
debug - got heartbeat packet
debug - cleared heartbeat timeout for client ZR-xQhsKCCqM03TRHW4b
debug - set heartbeat interval for client ZR-xQhsKCCqM03TRHW4b
测试成功。6. 最后总结今天尝试了4种,基于nodejs的websocket的框架。
node-websocket-server:是直接放弃的。
node-websocket:需要依赖于底层的C++,Python的环境,支持以node做客户端的访问。
faye-websocket-node:是faye软件框架体系的一部分,安装简单,不需要其他依赖库。
socket.io:功能强大,支持集成websocket服务器端和Express3框架与一身。
websocket我也是初次尝试,对于开发效率,代码结构,稳定性,服务器性能都需要做更多的测试。目前还无法定论,哪个框架是最好的,不过我比较看好socket.io和faye-websocket-node的未来前景。
转载请注明出处:

我要回帖

更多关于 c websocket 服务端 的文章

 

随机推荐