socket.io

2020-04-10 14:33:27 浏览数 (1)

前言

本译文来源于https://socket.io/get-started/chat/,不足之处请多批评指正。 最近在学些vuejs和websocket相关技术,使用了websocket的两个封装的库vue-socket.io和vue-websocket

  • vue-socket.io Vue-Socket.io is a socket.io integration for Vuejs, easy to use, supporting Vuex and component level socket consumer managements
  • vue-websocket vue-websocket-A socket.io plugin for Vue.js. This package does not support native websockets. At the time, we recommend using vue-native-websocket or implementing it yourself. For ongoing discussion on this, please visit #2.
  • vue-native-websocket https://github.com/nathantsoi/vue-native-websocket https://www.npmjs.com/package/vue-native-websocket

具体的实现详见对应的npm官网vue-socket.io和vue-websocket

socket.io

在本指南中,我们将创建一个基本的聊天应用程序。 它几乎不需要Node.JS或Socket.IO的基础知识,因此非常适合所有知识水平的用户。

介绍

传统上,使用像LAMP(PHP)这样的流行Web应用程序技术栈编写聊天应用程序非常困难。 它涉及到轮询服务器的更改,跟踪时间戳,并且比预期的要慢得多。

传统上,套接字是围绕其构建大多数实时聊天系统的解决方案,它提供了客户端和服务器之间的双向通信通道。

这意味着服务器可以将消息推送到客户端。每当你发送一条聊天信息时,其思想都是服务器将得到它并将其推送到所有其他连接的客户端。

网络框架

第一个目标是建立一个简单的HTML网页,以提供表单和消息列表。 为此,我们将使用Node.JS网络框架Express。 确保已安装Node.JS。

首先,我们创建一个描述我们项目的package.json清单文件。 我建议您将其放置在专用的空白目录中(我称之为mine chat-message)。

代码语言:javascript复制
{
  "name": "socket-chat-example",
  "version": "0.0.1",
  "description": "my first socket.io app",
  "dependencies": {}
}

现在,为了轻松地用我们需要的东西填充dependencies属性,我们将使用npm install:

代码语言:javascript复制
npm install express@4.15.2

现在已经安装了express,我们可以创建一个index.js文件来设置我们的应用程序。

代码语言:javascript复制
var app = require('express')();
var http = require('http').createServer(app);

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

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

上面的翻译转换如下:

  • Express将app初始化为可以提供给HTTP服务器的函数处理程序(如第2行所示)。
  • 我们定义了一个路由处理函数/,当我们访问我们的网站主页时会被调用。
  • 我们使http服务器在端口3000上侦听。 如果运行node index.js,则应看到以下内容:

如果你访问你的浏览器,指向http://localhost:3000

提供html

到目前为止,在index.js中,我们调用res.send并为其传递HTML字符串。 如果仅将整个应用程序的HTML放在此处,我们的代码就会看起来很混乱。 相反,我们将创建一个index.html文件并将其提供。

让我们重构路由处理程序,改为使用sendFile:

代码语言:javascript复制
app.get('/', function(req, res){
  res.sendFile(__dirname   '/index.html');
});

并使用以下内容填充index.html:

代码语言:javascript复制
<!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>

如果重新启动该程序(通过单击Control C并再次运行node index)并刷新页面,则它应如下所示:

集成Socket.IO

Socket.IO由两部分组成:

  • 与Node.JS HTTP Server集成(或安装在其上)的服务器:socket.io
  • 在浏览器端加载的客户端库:socket.io-client 如我们所见,在开发过程中,socket.io为我们自动为客户端提供服务,因此,现在我们只需要安装一个模块:
代码语言:javascript复制
npm install socket.io

这将安装模块并将依赖项添加到package.json。 现在,我们来编辑index.js来添加它:

代码语言:javascript复制
var app = require('express')();
var http = require('http').createServer(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(HTTP服务器)对象来初始化socket.io的新实例。 然后,我侦听将要到来的套接字的连接事件,并将其记录到控制台。

现在在index.html中,在</ body>之前添加以下代码段:

代码语言:javascript复制
<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io();
</script>

这就是加载socket.io-client所需的全部工作,它暴露出一个io全局(和端点GET /socket.io/socket.io.js),然后进行连接。

如果要使用客户端JS文件的本地版本,可以在node_modules / socket.io-client / dist / socket.io.js中找到它。

请注意,我在调用io()时未指定任何URL,因为它默认为尝试连接到为该页面提供服务的主机。

如果现在重新启动该过程(通过单击Control C并再次运行node index),然后刷新网页,则应该看到控制台打印“a user connected”。

尝试打开多个标签,您会看到几则消息:

每个套接字还会触发一个特殊的disconnect事件:

代码语言:javascript复制
io.on('connection', function(socket){
  console.log('a user connected');
  socket.on('disconnect', function(){
    console.log('user disconnected');
  });
});

那么,如果您多次刷新标签页,则可以看到它的作用:

发射事件

Socket.IO的主要思想是可以发送和接收所需的任何事件以及所需的任何数据。 任何可以被编码为JSON的对象都可以,并且也支持二进制数据。

让我们做到这一点,以便用户输入消息时,服务器将其作为聊天消息事件来获取。 现在index.html中的脚本部分应如下所示:

代码语言:javascript复制
<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(e){
      e.preventDefault(); // prevents page reloading
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
  });
</script>

在index.js中我们打印出chat message事件监听到的消息到控制台中

代码语言:javascript复制
io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    console.log('message: '   msg);
  });
});

结果应类似于以下视频:

广播

我们的下一个目标是将事件从服务器发送给其他用户。

为了向所有人发送事件,Socket.IO给了我们io.emit:

代码语言:javascript复制
io.emit('some event', { someProperty: 'some value', otherProperty: 'other value' }); // This will emit the event to all connected sockets

如果您想向除某个发射套接字之外的所有人发送消息,我们有从该套接字发射的broadcast标记:

代码语言:javascript复制
io.on('connection', function(socket){
  socket.broadcast.emit('hi');
});

在这种情况下,为简单起见,我们会将消息发送给所有人,包括发送者。

代码语言:javascript复制
io.on('connection', function(socket){
  socket.on('chat message', function(msg){
    io.emit('chat message', msg);
  });
});

在客户端,当我们捕获chat message事件时,会将其包括在页面中。 客户端JavaScript代码现在变成:

代码语言:javascript复制
<script>
  $(function () {
    var socket = io();
    $('form').submit(function(e){
      e.preventDefault(); // prevents page reloading
      socket.emit('chat message', $('#m').val());
      $('#m').val('');
      return false;
    });
    socket.on('chat message', function(msg){
      $('#messages').append($('<li>').text(msg));
    });
  });
</script>

大约20行代码就完成了我们的聊天应用程序! 看起来是这样的:

家庭作业

以下是一些改进应用程序的想法:

  • 当有人连接或断开连接时,向连接的用户广播消息。
  • 添加对昵称的支持。
  • 不要将相同的消息发送给自己发送的用户。 相反,请在他按下Enter键后立即直接添加消息。
  • 添加“ {user}正在键入”功能。
  • 显示谁在线。
  • 添加私人消息。
  • 分享您的改进!

得到这个示例

您可以在GitHub上找到它。

代码语言:javascript复制
git clone https://github.com/socketio/chat-example.git

弄错了吗? 在GitHub上编辑此页面

0 人点赞