websocket
1.通过websocket协议握手
2.后续通过tcp流方式交互
这个文章可以作为一个协议简介
在PC上试用,winxp,软件包选用了WebSocket-Node,websocket协议的nodejs扩展包
安装:
* npm install -g node-gyp
* npm install websocket
* server端代码(ws_demo_server.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 = 9000;
// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');
/**
* Global variables
*/
// latest 100 messages
var history = [ ];
// list of currently connected clients (users)
var clients = [ ];
/**
* 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,
autoAcceptConnections: false
});
function msg_history(userName, friend, msg){
var history = {
type: 'message',
time: (new Date()).getTime(),
msg: msg,
user: userName,
friend: friend,
};
return history;
}
function reg_user(userName, host, port) {
// put logic here to detect whether the specified origin is allowed.
return true;
}
// 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 = false;
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
var msgObj = JSON.parse(message.utf8Data);
userName = msgObj['data']['userName'];
console.log((new Date()) + ' User : ' + userName );
// get random color and send it back to the user
var msg = msg_history(userName, msgObj['data']['userFirend'], msgObj['data']['talkMsg']);
connection.sendUTF(JSON.stringify(msg));
} 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 msgObj = JSON.parse(message.utf8Data);
var msg = msg_history(msgObj['data']['userName'], msgObj['data']['userFirend'], msgObj['data']['talkMsg']);
history.push(msg);
history = history.slice(-100);
// broadcast message to all connected clients
var json = JSON.stringify(msg);
for (var i=0; i < clients.length; i++) {
clients[i].sendUTF(json);
}
}
}else if (message.type === 'binary') {
console.log('Received Binary Message of ' + message.binaryData.length + ' bytes');
connection.sendBytes(message.binaryData);
}else {
console.log('Received Unknow Type Message');
connection.sendBytes('Received Unknow Type Message');
}
});
// user disconnected
connection.on('close', function(connection) {
if (userName !== 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
}
});
});
* clien端代码(ws_demo_client.html)
(也是半抄半改,chrom下OK,测试要多开几个页面)
<html>
<head>
<script type="text/javascript">
var host = '127.0.0.1';
var port = 9000;
var url = 'ws://'+host+':'+port+'/';
var w = new WebSocket(url);
w.onopen = function(){
$('stat-box').innerHTML = '已连接到服务器......<br/>';
}
function json2str(json){
return JSON.stringify(json)
}
function str2json(str){
return JSON.parse(str);
}
w.onmessage = function(e){
var obj = str2json(e.data);
var chatBox = $('chat-box');
if (typeof(obj.type) == undefined) {
} else if (obj.type == 'history') {
for(var idx in obj.data){
var time = Math.round(obj.data[idx]['time'] / 1000);
var fromWho = obj.data[idx]['user'];
var toWho = ( "" == obj.data[idx]['friend'] ) ? "所有人" : obj.data[idx]['friend'];
var msg = obj.data[idx]['msg'];
chatBox.innerHTML = chatBox.innerHTML + time + ':<br/> ' + fromWho + " 对 " + toWho + " 说:" + msg + '<br/>';
}
} else if (obj.type == 'message') {
var time = Math.round(obj['time'] / 1000);
var fromWho = obj['user'];
var toWho = ( "" == obj['friend'] ) ? "所有人" : obj['friend'];
var msg = obj['msg'];
chatBox.innerHTML = chatBox.innerHTML + time + ':<br/> ' + fromWho + " 对 " + toWho + " 说:" + msg + '<br/>';
}
}
function send(){
var userName = $('userName');
var userFirend = $('userFirend');
var talkMsg = $('talkMsg');
var msgToSend={"data":{"userName":userName.value,"userFirend":userFirend.value,"talkMsg":talkMsg.value}};
w.send(json2str(msgToSend));
}
function $(id){
return document.getElementById(id);
}
</script>
</head>
<body>
<div id="chat-box" style="bordddder:1px solid #cccccc; width:400px; height:400px; overflow:scroll;"></div>
<div id="stat-box" style="bordddder:1px solid #cccccc;"></div>
昵称 :<input type="text" id="userName"/><br/>
发给朋友:<input type="text" id="userFirend"/><br/>
内容 :<input type="text" id="talkMsg"/><br/>
<input type="button" id="send" onClick="send();" value="发送"/>
</body>
</html>