Node.js和Socket.IO搭建Web Chat application

WebSocket与Socket.IO

WebSocket是一种协议,有了它就能够在TCP协议的基础上在浏览器和服务器之间创建起了一种全双工的通道,它彻底兼容HTTP协议,有了它使得Web应用程序能够在浏览器和服务器之间进行实时的交互,如今主流浏览器都支持这种协议。html


Socket.IO是JavaScript library,是Node.js的module,它能够创建起一个基于事件的实时的双向交流方式,极大的简化了WebSocket的处理过程。在这个Chat application中将会用到它。node

开始Chat application

搭建这个应用几乎只须要Node.js和Socket.IO最初级的知识,由于只搭建一个基本的程序。jquery

web 框架

最初的构想是一个简单的HTML页面,由一个表单和消息列表组成,要使用Node.js和express框架,首先确保Node.js已经安装好了。web


首先建立项目目录chat-example文件夹,而后在里边建立package.json文件来描述项目信息以及依赖。express

{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {}
}

而后到命令行cd到项目目录安装express,npm install --save express
--save参数能够把自动把express添加到package.json的dependencies中。
express安装好后建立一个index.js,来配置应用。npm

//index.js
var app = require('express')();
var http = require('http').Server(app);

app.get('/', function(req, res){
  res.send('<h1>Hello world</h1>');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

上边代码能够这样翻译一下:json

  1. Express初始化了一个函数句柄能够应用于HTTP server于第2行浏览器

  2. 定义一个路由来访问网站首页服务器

  3. 开启http服务监听3000端口app

在命令行中node index.js获得以下结果:
图片描述
到浏览器中访问http://localhost:3000结果以下:
图片描述

以前咱们使用res.send('<h1>Hello world</h1>');来传递html字符串,若是文档内容多了这样作就有点low了,换种方式新建一个index.html文件,访问它就能够了。

首先来重构以前的路由:

app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});

而后建立index.html

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </body>
</html>

重启服务,到浏览器查看是这个样子:
图片描述

把Socket.IO引入

Socket.IO由2部分组成:

  • 服务端Node.JS HTTP Server: socket.io

  • 浏览器端的js库:socket.io-client

接下来npm install --save socket.io添加模块
而后编辑index.js中的内容以下:

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function(req, res){
  res.sendFile(__dirname + '/index.html');
});

io.on('connection', function(socket){
  console.log('a user connected');
});

http.listen(3000, function(){
  console.log('listening on *:3000');
});

注意经过把http(the HTTP server)对象传递给socket.io初始化了一个socket.io的实例,而后监听connection事件,而且在控制台中打印出来

在index.html的</body>以前增长以下几行:

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

这就是用来加载socket.io-client的,暴露出一个全局的io,而后connect
注意我调用io()的时候并无指定任何的URL,由于它默认就是去当前跑的页面去和server链接
重启服务,多开几个页面,在控制台中能够看到以下结果:
图片描述

每一个socket还有一个特殊的disconnect事件:

io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

发射事件

Socket.IO的主要想法就是你可以发射和接收任何你喜欢的事件,任何对象都会被编码成Json,也支持二进制数据


那接下来就作咱们发送信息的时候server接收到chat message事件,index.html中的script部分改写以下:

<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
  });
</script>

在index.js中咱们打印出chat message事件

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: ' + msg);
  });
});

在浏览器端发射,控制台观察以下:
图片描述

广播消息Broadcasting

接下来的目标是从server发送消息给其他的在线用户,为了能把消息传递给everyone,Socket.IO给咱们提供了io.emit

io.emit('some event', { for: 'everyone' });

若是你想发消息给everyone,除去一个特定的socket,那就快用broadcast 标志吧

io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});

像下面这样就能把消息发给全部人,包括消息的发送者

io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

下面到客户端捕获chat message事件,把消息内容插到消息列表中:

<script>
  $(function () {
    var socket = io();
    $('form').submit(function(){
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

到浏览器多开几个选项卡就能够疯狂的发射和接收消息了,很是实时,短短20几行代码就能实现这样的效果,真是使人发指啊!

总结

哈哈,其实这个例子是socket.io官网的小栗子,喜欢学英语的朋友能够去玩一下,那里的video演示很直观,你能够戳这里socket.io-Chat

相关文章
相关标签/搜索