node.js和websocket实现echo

= 1126

本文出自:【InTheWorld的博客】

     最近在学习Node.js,其中一章讲了WebSocket相关的内容。我看的书是《了不起的node.js》。这本书中实现了一个echo例子,但是我照书上做的程序却出现了错误。书中使用了express和websocket.io实现的这个例子。然而例子的express版本还是古老的2.5.1,最新的已经是4..了,所以出了问题也不奇怪。
     书中的服务器代码片段大概是这样的:

var express = require('express')
    , wsio = require("websocket.io")

var app = express.createServer();

var ws = wsio.attach(app);

app.use(express.static('public'));
/* 
*
*/
app.listen(3000);   

前端代码index.html如下:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>websocket echo</title>
</head>
<body>
<h1>websocket echo</h1>
<h2>latency:<span id="latency"></span>ms</h2>
<script>

    var lastMessage;
    window.onload=function(){
        //create socket

        var ws=new WebSocket('ws://127.0.0.1:3000');
        ws.onopen=function(){
            //send first ping
            ping();
        };
        console.log("going well!");
        // 监听Socket的关闭
        ws.onclose = function(event) {
            console.log('Client notified socket has closed',event);
        };
        ws.onmessage=function(ev){
            console.log("got:"+ev.data);

            document.getElementById("latency").innerHTML=new Date-lastMessage;
            ping();
        };
        function ping(){
            lastMessage = new Date;
            ws.send("ping");
        }
    }
</script>
</body>
<html>

       查了资料才知道新版的express已经没有createServer()这个方法了。然后我参考express 4.x的api文档改程序,也还是解决不了,浏览器显示“Connection closed before receiving a handshake response”。仔细回想一下,还是觉得自己没有理解express,所以就决定先不用express,而是直接用http。

var http = require('http')
    // use require('websocket.io') if you installed with NPM
  , wsio = require('websocket.io')

/**
 * Create HTTP server.
 */

var server = http.createServer(function (req, res) {
  res.writeHead(200, { 'Content-Type': 'text/html' });
  res.end([
  '<!DOCTYPE html>'
    ,'<html>'
    /*index.html的内容*/
    ,'</html>'   
  ].join(''));
});

var ws = wsio.attach(server);

ws.on('connection', function (socket) {
    socket.on('message', function (msg) {
        console.log(' \033[96mgot:\033[39m ' + msg);
        socket.send('pong');
    });
});

server.listen(3000);

      运行结果是正确的。然而这个正确代码看起来很不舒服,前端代码和服务器代码耦合在一起,长长的字符串数组我都不敢把它们贴上来。而且调试的时候根本看不清楚,所以我还是想用express的静态托管功能。于是继续看express的api。然后看到了:
       var express = require(‘express’);
       var http = require(‘http’);
       var app = express();
       http.createServer(app).listen(80);

       原来app其实一个函数,所以可以使用它来创建传统的httpserver。然后我就得到了如下的服务器端代码:

var express = require('express')
    , wsio = require('websocket.io')
    , http = require('http')

var app = express();

app.use(express.static('public'));

var server = http.createServer(app) 

var ws = wsio.attach(server);


ws.on('connection', function (socket) {
    socket.on('message', function (msg) {
        console.log(' \033[96mgot:\033[39m ' + msg);
        socket.send('pong');
    });
});

server.listen(3000);

        运行效果也是正常的(index.html在public子目录下,和前文中的内容是一样的。:)

发表评论