为了创建一个web聊天室,那么首先和传统信息项目不一样的地方在于,我们不止要从服务器端获取信息,同时我们还需要服务器主动的给我们推送数据.推送这个词我觉得很好,不仅仅是浏览器客户端将信息或者请求发送给服务器,服务器也要主动的将信息发送给客户端.
socket.io 是一个为实时应用提供跨平台实时通信的库。socket.io 旨在使实时应用在每个浏览器和移动设备上成为可能,模糊不同的传输机制之间的差异
Nodejs中我们使用socket.io的来实现这一目的,这是一个在基于Nodejs平台下的,已经封装好的WebSocket实现,通过它来实现浏览器和服务器端的双向实时通道,当然现在不是所有的浏览器都支持WebSocket,不过不用担心,socket.io已经集成了多种方式去实现,即使客户端不支持websocket也会自动使用其他方式.详细的可以查看socket.io的官网:http://socket.io/,查看Supported transports我们可以看到它实现的多种方式.
我们在系列一中,先来实现一个简单的demo,也是聊天室的基础骨架,做一个统计在线人数并且可以简单发送消息的这样一个功能.
首先确定,我们不适用Express,使用nodejs原生即可,文件不多,代码很少没必要用上框架.没有安装Nodejs的朋友或者Nodejs基础为零的同学可以自行百度安装,很简单,现在我们开始.
1.首先,在E盘创建一个文件夹,这里就叫做SocketIODemo1,在其中创建一个package.json文件.有Nodejs基础的同学会知道,这是一个配置文件,在里面配置好我们项目需要的模块,然后可以通过npm安装.
打开新创建的package.json文件,在其中写下如下代码:
{ "name":"SocketIO", "version":"0.0.1", "private":true, "dependencies":{ "socket.io":"*" } }
在当前需求下,我们只需要socket.io,"*"表示要下载最新版本.然后我们cmd打开命令行输入:
E: cd SocketIO npm install这样npm会根据我们的配置文件,自动去下载所需要的模块文件,接下来我们来编写服务器端代码,在文件夹内继续创建一个app.js文件,开始写入代码:
var http = require('http'); var fs = require('fs'); //创建一个HTTP服务器,一旦有请求发送到这个服务器监听地址,则开始处理请求 var server = http.createServer(function (req, res) { //这里的含义则是,不管什么请求,都去读取同目录下index.html文件,并将其内容返回给请求. fs.readFile('./index.html', function(error, data) { res.writeHead(200, { 'Content-Type': 'text/html' }); res.end(data, 'utf-8'); }); }).listen(3000, "127.0.0.1"); console.log('Server running at http://127.0.0.1:3000/'); //将SocketIO库包含进来,并绑定到服务器上. var io = require('socket.io').listen(server); var count = 0; //监听所有到服务器上的连接. io.sockets.on('connection', function (socket) { //有新的连接,count加1,将现在的总连接数,广播给所有用户. count++; socket.emit('usernum',{number:count}); socket.broadcast.emit('usernum',{number:count}); //一旦有请求,连接到服务器,则监听message事件,读取信息,然后将这个信息广播给所有的连接,包括新的连接和老的连接. socket.on('message', function (data) { socket.emit('push message', data); socket.broadcast.emit('push message', data); }); //监听断开连接,count减1,然后将总连接数发送给其他全部客户端 socket.on('disconnect',function(){ count--; socket.broadcast.emit('usernum',{number:count}); }); });
写完这些,我们服务器方面的处理就完成了,其中大部分代码我已经加入注释方便大家阅读,有问题可以留言给我.这里说明一下就是io.sockets.on的监听方法中socket.emit和socket.broarcast.emit的区别.前者是将消息发送给触发事件的浏览器,这里就是新连接的浏览器.后者是将消息发送给所有之前就已经连接的浏览器.这两个加在一起,才是广播给全部的连接.
然后我们继续创建html文件,也就是客户端,新建一个index.html文件,在其中编写代码:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8" /> <title>Socket.IO Example</title> </head> <body> <h1>Socket.IO Example</h1> <h1 id="usernum"></h1> <form id="message-form" action="#"> <textarea id="message" rows="4" cols="30"></textarea> <input type="submit" value="Send message" /> </form> <!-- 将jquery和SocketIO的库包含进来,SocketIO如果服务器和客户端在同一服务器(同一项目中),那么这里会自动引入这个SocketIO客户端js --> <script src="http://sandbox.runjs.cn/js/sandbox/jquery/jquery-1.8.2.min.js"></script> <script src="/socket.io/socket.io.js"></script> <script> //指示浏览器连接位于http://127.0.0.1:3000的SocketIO服务器 var socket = io.connect('http://127.0.0.1:3000'); //监听服务器广播的usersnum事件 socket.on('usernum',function(data){ $("#usernum").html("当前连接人数:" + data.number); }); var message = document.getElementById('message'); $(message.form).submit(function() { //表单提交发送信息给SocketIO服务器,服务器端监听message事件即可获取到信息. socket.emit('message', { text: message.value }); return false; }); //客户端监听push message事件,这是服务器端广播的,广播给除了发送消息的浏览器之外的全部浏览器 socket.on('push message', function (data) { $('form').after('<p>' + data.text + '</p>'); }); </script> </body> </html>
这里我们在客户端引入了两个js文件,一个jquery另一个就是socket.io.我要说明一下,socket.io客户端js文件的引入之所以可以这么写,是因为我们服务器端引用了socket.io的模块,所以这里客户端文件直接通过这种写法引入.而jqeury这里是引用了一个外部网址,而不是我们项目内的一个jquery文件.因为我们没有功能区处理静态文件的加载,也就是css,js这些文件.而在我们创建的http服务器中,对于链接请求没有这方面处理,所以即使有jquery文件我们也法成功加载.
这里我们暂时这么写,后续或者会有一个静态文件服务器的写法给大家或者直接使用Express框架.
现在index.html,app.js,package.json这3个文件都完成了,我们的这个小demo也算可以运行,打开cmd命令行,进入当前文件夹,输入node app.js
看一下效果截图: