10

socket.io非常适合做聊天室,但英文官网读起来还是有一定的障碍,特此翻译。如有误点,欢迎指出。

原地址:http://socket.io/get-started/chat/

正文如下:

开始:聊天

本篇文章,我们将一起来创建一个简单的聊天应用。它几乎不要求你提前掌握Node.JS 或 Socket.IO的知识,适合任何人来尝试。

介绍

用LAMP这种传统的方式来搭建一个聊天应用是很难的,它包括轮询服务器的变化,保持跟踪时间戳,比socket.io慢得多。

Sockets一直是最具实时性的聊天系统解决方案,在客户端和服务端提供了一种双向通信通道。

这意味着服务器能发送消息给客户端。当你发出一条消息时,服务端将获取它,并将它发送给其他所有在线客户端。

使用web框架 express

首要目标是建立一个简单的HTML页面,包括一个表单和一个消息列表,我们将使用Node.JS web 框架 express 去搭建。请先确保 Node.JS 已经安装。

首先为我们的应用新建一个package.json配置文件,把它放到一个新建的文件夹中(例如chat-example)。

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

现在为了更快的将我们需要的依赖应用添加到dependencies中,运行npm install --save

npm install --save express@4.10.2

现在express已经安装好了,我们再新建一个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');
});

说明如下:

  1. Express初始化app为一个处理请求HTTP服务的程序。(参见第二行)

  2. 定义一个路由/访问网站根目录

  3. 监听HTTP服务器端口3000

如果你运行node index.js,将看到如下界面:
图片描述

紧接着我们用浏览器访问http://localhost:3000
图片描述

编辑HTML(Serving HTML)

现在我们在index.js中使用res.send传递一个HTML字符串。如果我们把整个应用的的HTML放在index.js中,整个代码结构将杂乱无章。所以我们要创建一个index.html文件。

我们要使用sendFile方法来重构路由管理。

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

index.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>

如果你重启进程(ctrl+C并再次运行node index)并且刷新浏览器,效果如下:

图片描述

整合Socket.IO

Socket.IO由两部分构成:

  • 服务端使用Node.JS的HTTP服务器: socket.io

  • 客户端则在浏览器端加载:socket.io-client

开发期间,socket.io自动在客服端运行加载,现在我们必须要安装一个模块:

npm install --save socket.io

上面的命令将安装socket.io模块,并将它写入配置文件package.json。然后我们修改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('index.html');
});

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

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

注意,我通过使用http(http服务器)对象来初始化一个socket.io实例。接着监听socket连接事件,并将它输出到控制台。

然后在index.html</body>之前加入以下片段:

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

客户端加载socket.io-client,在全局调用io()并连接服务端。

注意,当我们调用io()时没有指定任何一个URL,因为它默认去尝试连接主机。

如果你现在重载服务器和客户端,控制台打印“a user connected”。

尝试打开多个页面,你将看到如:

图片描述

每个socket也触发特殊的disconnect事件。

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

如果你刷新一个页面几次,你将在控制台看到如下信息:

图片描述

发送事件(Emitting)

Socket.IO背后的主要思想是:你可以发送和接收任何你想要的事件和数据。任何被编码为JSON的对象,二进制数据也支持。

当用户输入一条消息时,服务端把它当作chat message事件获得。在index.html中的script片段如下:

<script src="https://cdn.socket.io/socket.io-1.2.0.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
  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)

下一个目标是将来自服务器的消息发送给其他用户。

为了发送给每一个人,Socket.IO提供io.emit了给我们:

io.emit('some event', { for: '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事件。客户端全部的 JavaScript 代码如下:

<script>
  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行代码,最后就是这样子了:(原文是一小片段视频,此处无法加进来,截图展示)

图片描述

更多的实践

这有一些建议来改进这个应用:

  • 当有人进入或离开时,通知给所有人。

  • 增加昵称

  • 不发送相同的消息给发送者自己,反而当输入回车时快速发送消息。

  • 增加“用户正在输入”功能

  • 展示谁在线

  • 增加私信

  • 分享你的改进

获得这个例子

在GitHub上你能找到它

$ git clone https://github.com/guille/chat-example.git

译者说:

这篇文章还是有几处我没有翻译好的地方,作为一个coder必须要把英语学好。好事多磨,编程也不要过分地追求速度。


桃源小盼聊技术
733 声望16 粉丝

努力做到优秀。