Node.js + WebSocket 实现的简易聊天室

分类:技术文档 - JS文档 | 阅读(3451) | 发布于:2014-03-07 09:13

实例程序在Windows下测试通过。

实例支持以下浏览器:

Firefox 7-9 (Old) (Protocol Version 8)
Firefox 10+ (Protocol Version 13)
Chrome 14,15 (Old) (Protocol Version 8)
Chrome 16+ (Protocol Version 13)
Internet Explorer 10 (Preview) (Protocol Version 13)


消息的传递也比较简单,Client –> Server, Server –> Client


服务器广播消息



数据传输使用的是JSON格式,前台建立连接的代码比较简单,ex:

 1: $(function () {
 2: window.WebSocket = window.WebSocket || window.MozWebSocket;
 3: 
 4: var connection = new WebSocket('ws://127.0.0.1:1337');
 5: 
 6: connection.onopen = function () {
 7: //已建立连接
 8: };
 9: 
 10: connection.onerror = function (error) {
 11: //接收或发送消息时遇到了错误
 12: };
 13: 
 14: connection.onmessage = function (message) {
 15: 
 16: try {
 17: var json = JSON.parse(message.data);
 18: } catch (e) {
 19: console.log('不能被正常解析的数据:', message.data);
 20: return;
 21: }
 22: 
 23: // todo
 24: };
 25: });

后端的实现,直接使用别人写好的模块所以传统比较简单一点(想在Windows下运行chat-server还是有点麻烦 的),因为该模块在 Windows下安装时,需要Microsoft Visual C++和Python 2.7的支持。--如果没有安装这两个东东,还得先安装一下。

如果顺利的话,会看到如下图所示的界面:

这样我们就可以创建Server了,实现的代码也并不复杂:

 1: var WebSocketServer = require('websocket').server;
 2: var http = require('http');
 3: 
 4: var server = http.createServer(function(request, response) {
 5: console.log((new Date()) + ' Received request for ' + request.url);
 6: response.writeHead(404);
 7: response.end();
 8: });
 9: server.listen(8080, function() {
 10: console.log((new Date()) + ' Server is listening on port 8080');
 11: });
 12: 
 13: wsServer = new WebSocketServer({
 14: httpServer: server,
 15: // You should not use autoAcceptConnections for production
 16: // applications, as it defeats all standard cross-origin protection
 17: // facilities built into the protocol and the browser.  You should
 18: // *always* verify the connection's origin and decide whether or not
 19: // to accept it.
 20: autoAcceptConnections: false
 21: });
 22: 
 23: function originIsAllowed(origin) {
 24: // put logic here to detect whether the specified origin is allowed.
 25: return true;
 26: }
 27: 
 28: wsServer.on('request', function(request) {
 29: if (!originIsAllowed(request.origin)) {
 30: // Make sure we only accept requests from an allowed origin
 31: request.reject();
 32: console.log((new Date()) + ' Connection from origin ' + request.origin + ' rejected.');
 33: return;
 34: }
 35: 
 36: var connection = request.accept('echo-protocol', request.origin);
 37: console.log((new Date()) + ' Connection accepted.');
 38: connection.on('message', function(message) {
 39: if (message.type === 'utf8') {
 40: console.log('Received Message: ' + message.utf8Data);
 41: connection.sendUTF(message.utf8Data);
 42: }
 43: else if (message.type === 'binary') {
 44: console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
 45: connection.sendBytes(message.binaryData);
 46: }
 47: });
 48: connection.on('close', function(reasonCode, description) {
 49: console.log((new Date()) + ' Peer ' + connection.remoteAddress + ' disconnected.');
 50: });
 51: });

从上述的例子中可以看出,websocket支持两种传递方式:二进制流、utf8的文本流。前面的例子中所使用的是utf8文本流


完整的chat-server.js的代码如下:

 1: // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/
 2: "use strict";
 3: 
 4: // Optional. You will see this name in eg. 'ps' or 'top' command
 5: process.title = 'node-chat';
 6: 
 7: //websocket服务器监听的端口
 8: var webSocketsServerPort = 1337;
 9: 
 10: var webSocketServer = require('websocket').server;
 11: var http = require('http');
 12: 
 13: //保存最近100条消息记录
 14: var history = [ ];
 15: 
 16: //当前连接的客户端
 17: var clients = [ ];
 18: 
 19: /**
 20:  * 对聊天内容进行字符转义
 21:  */
 22: function htmlEntities(str) {
 23: return String(str).replace(/&/g, '&').replace(/'<').replace(/>/g, '>').replace(/"/g, '"');
 24: }
 25: 
 26: 
 27: var colors = [ 'red', 'green', 'blue', 'magenta', 'purple', 'plum', 'orange' ];
 28: colors.sort(function(a,b) { return Math.random() > 0.5; } );
 29: 
 30: /**
 31: * HTTP server
 32: */
 33: var server = http.createServer(function(request, response) {});
 34: 
 35: server.listen(webSocketsServerPort, function() {
 36: console.log(getNow() + " WebSocket Server is listening on port:" + webSocketsServerPort);
 37: });
 38: 
 39: /**
 40: * WebSocket server
 41: * WebSocket server is tied to a HTTP server. To be honest I don't understand why.
 42: */
 43: var wsServer = new webSocketServer({
 44: httpServer: server
 45: });
 46: 
 47: //每一个客户端请求建立连接时,都将触发此方法
 48: wsServer.on('request', function(request) {
 49: 
 50: console.log(getNow() + ' ' + request.origin + ' 请求连接.');
 51: 
 52: // accept connection - you should check 'request.origin' to make sure that client is connecting from your website
 53: // (http://en.wikipedia.org/wiki/Same_origin_policy)
 54: var connection = request.accept(null, request.origin); 
 55: 
 56: //保存当前请求连接客户端的索引,以方便在断开连接时,从连接池中移除该连接
 57: var index = clients.push(connection) - 1;
 58: var userName;
 59: var userColor;
 60: 
 61: console.log(getNow() + ' 已建立连接...');
 62: 
 63: //推送历史聊天记录
 64: if (history.length > 0) {
 65: connection.sendUTF(JSON.stringify({type: 'history', data: history}));
 66: }
 67: 
 68: //某一客户端发送消息过来
 69: connection.on('message', function(message) {
 70: if (message.typ

标签: