Node.js 教程第十三篇——WebSocket

LogicCascade
• 阅读 6161

重温 HTTP 协议

HTTP 协议可以总结几个特点:

  • 一次性的、无状态的短连接:客户端发起请求、服务端响应、结束。
  • 被动性响应:只有当客户端请求时才被执行,给予响应,不能主动向客户端发起响应。
  • 信息安全性:得在服务器添加 SSL 证书,访问时用 HTTPS。
  • 跨域:服务器默认不支持跨域,可在服务端设置支持跨域的代码或对应的配置。

认识 TCP

TCP 协议可以总结几个特点:

  • 有状态的长连接:客户端发起连接请求,服务端响应并建立连接,连接会一直保持直到一方主动断开。
  • 主动性:建立起与客户端的连接后,服务端可主动向客户端发起调用。
  • 信息安全性:同样可以使用 SSL 证书进行信息加密,访问时用 WSS 。
  • 跨域:默认支持跨域。

认识 WebSocket

WebSocket 目前由 W3C 进行标准化。WebSocket 已经受到 Firefox 4、Chrome 4、Opera 10.70 以及Safari 5 等浏览器的支持。
如果在前端我们可以把 AJAX 请求当作一个 HTTP 协议的实现,那么,WebSocket 就是 TCP 协议的一种实现。

服务端 API

  • 安装第三方模块 ws:npm install ws
  • 开启一个 WebSocket 的服务器,端口为 8080
var socketServer = require('ws').Server;
var wss = new socketServer({
    port: 8080
});
  • 也可以利用 Express 来开启 WebSocket 的服务器
var app = require('express')();
var server = require('http').Server(app);

var socketServer = require('ws').Server;
var wss = new socketServer({server: server, port: 8080});
  • 用 on 来进行事件监听
  • connection:连接监听,当客户端连接到服务端时触发该事件
  • close:连接断开监听,当客户端断开与服务器的连接时触发
  • message:消息接受监听,当客户端向服务端发送信息时触发该事件
  • send: 向客户端推送信息
wss.on('connection', function (client) {
    client.on('message', function (_message) {
        var _messageObj = JSON.parse(_message);
        //status = 1 表示正常聊天
        _messageObj.status = 1;
        this.message = _messageObj;
        //把客户端的消息广播给所有在线的用户
        wss.broadcast(_messageObj);
    });

    // 退出聊天  
    client.on('close', function() {  
        try{
            this.message = this.message || {};
            // status = 0 表示退出聊天
            this.message.status = 0;
            //把客户端的消息广播给所有在线的用户
            wss.broadcast(this.message);  
        }catch(e){  
            console.log('刷新页面了');  
        }  
    });  
});

//定义广播方法
wss.broadcast = function broadcast(_messageObj) {  
    wss.clients.forEach(function(client) { 
        client.send(JSON.stringify(_messageObj))
    });  
}; 

客户端 API

  • 在支持 WebSocket 的浏览器下实例化 WebSocket ,参数为 WebSocket 服务器地址,建立与服务器的连接
if(!WebSocket){
    $('.connState').text("您的浏览器不支持WebSocket");
    return false;
} 
//连接 socket 服务器
var socket = new WebSocket('ws://localhost:8080');
  • onopen:当网络连接建立时触发该事件
//监听 socket 的连接
socket.onopen = function(){
    $('.connState').text("服务已连接 ws://localhost:8080");
}
  • onclose:当服务端关闭时触发该事件
//监听服务端断开
socket.onclose = function(){
    $('.connState').text("服务已断开");
    socket = null;
}
  • close: 在客户端断开与服务端的连接 socket.close();
  • onerror:当网络发生错误时触发该事件
//监听服务端异常
socket.onerror = function(){
    $('.connState').text("服务错误");
    socket = null;
}
  • onmessage:当接收到服务器发来的消息的时触发的事件,也是通信中最重要的一个监听事件
//监听服务端广播过来的消息
socket.onmessage = function(msg){
    var msgObj = JSON.parse(msg.data);
    if(msgObj.status == 0){
        $('<p>' + msgObj.nickname + '[' + msgObj.time + ']退出聊天</p>').appendTo('.msgList');
    } else{
        $('<p>' + msgObj.nickname + '[' + msgObj.time + ']:' + msgObj.message + '</p>').appendTo('.msgList');
    }
}
  • send:向服务端推送消息
var sendMessage = function(_mess){
    if(socket){
        var myDate = new Date();
        var now = myDate.getMonth() + '-' + myDate.getDate() + ' ' + myDate.getHours() + ':' + myDate.getMinutes() + ':' + myDate.getSeconds();                
        
        var mesObj = {
            nickname: $('#nickName').val(),
            message: _mess || $('#mesBox').val(),
            time: now
        }
        //向服务端发送消息
        socket.send(JSON.stringify(mesObj));
    }            
}

项目应用

该案例是一个多人聊天室

运行步骤

  • npm install ws
  • node socketServer

案例思路

  • 服务端开户一个服务 new socketServer({port: 8080});
  • 客户端建立和服务端的连接 var socket = new WebSocket('ws://localhost:8080');
  • 建立连接的同时发送上线信息给服务端 socket.send('加入聊天');
  • 服务端接受到客户端的消息触发 message 方法,然后将该消息广播给所有在线的用户
  • 所有客户端收到来自服务端广播的消息,然后将该消息显示在聊天列表。
  • 聊天和退出聊天都是重复着客户端发送消息,服务端接受消息然后向客户端广播消息,客户端显示广播消息。
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
java 实现websocket
最近了解了下websocket和socket这个东西,说不得不来说下为何要使用WebSocket,和为何不用http。为何需要WebSocket?HTTP协议是一种无状态的、无连接的、单向的应用层协议。它采用了请求/响应模型。通信请求只能由客户端发起,服务端对请求做出应答处理。这种通信模型有一个弊端:HTTP协议无法实现服务器主
东方客主 东方客主
4年前
Http请求头和请求响应头大全
HTTP响应头和请求头信息对照表HTTP请求头提供了关于请求,响应或者其他的发送实体的信息。HTTP的头信息包括通用头、请求头、响应头和实体头四个部分。每个头域由一个域名,冒号(:)和域值三部分组成。通用头标:即可用于请求,也可用于响应,是作为一个整体而不是特定资源与事务相关联。请求头标:允许客户端传递
Stella981 Stella981
3年前
Django初识(web框架,django下载安装,http协议)
一web框架的本质及自定义web框架我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请求,服务端按照http协议的响应协议来响应请求,这样的网络通信,我们就
Stella981 Stella981
3年前
HTTP协议与WebSocket协议对比
1.HTTP从根本上讲,HTTP还是半双工的协议,也就是说,在同一时刻流量只能单向流动:客户端向服务器发送请求(单向),然后服务器响应请求(单向)。2.WebSocketWebSocket是一种自然的全双工、双向、单套接字连接。使用WebSocket,一旦建立连接,服务器与客户端可以随时发送消息。与HTTP轮询不同,WebSocket只发有一个请
Stella981 Stella981
3年前
Servlet主要相关类核心类 容器调用的过程浅析 servlet解读 怎么调用 Servlet是什么 工作机制
WEB简介Web项目是B/S结构浏览器/服务器模式的浏览器发起请求,服务器作出响应请求的发起和响应使用HTTP协议进行通讯所谓协议也就是一种固定格式而Socket是应用层与传输层的一层编程接口,屏蔽了传输层的细节所以Web项目也就是通过Socket发送HTTP请求和响应的过程只不过请求是浏览器发出来的响应是服务器发
Stella981 Stella981
3年前
Django_初识
HTTP协议超文本传输协议(应用层的,基于tcp\ip协议的)特点:无状态,无连接(短连接)请求消息格式:请求行\请求头部\空行\请求数据请求行:GET路径HTTP/1.1响应消息格式:响应行\响应头部\空行\响应数据响应行:HTTP/1.1状态码状态
Wesley13 Wesley13
3年前
HTTP状态码
消息(1字头)这一类型的状态码,代表请求已被接受,需要继续处理。这类响应是临时响应,只包含状态行和某些可选的响应头信息,并以空行结束。由于HTTP/1.0协议中没有定义任何1xx状态码,所以除非在某些试验条件下,服务器禁止向此类客户端发送1xx响应。100Continue客户端应当继续发送请求。这个临时响应是
Stella981 Stella981
3年前
Servlet知识小结
什么是Servlet?Servlet是运行于web服务器中的一个特殊java应用小程序,能够接受来自每个客户端的请求并给予响应,双方遵循http协议。Servlet是做什么的?1能够接收客户端的HTTP的请求,并给予不同的响应,即动态响应。2能做一些需要动态显示的Web资源内容。可自行查看JAVA的API了解Servlet、Gene
Stella981 Stella981
3年前
Http基础解析
Http基础解析\\概念\\:HyperTextTransferProtocol超文本传输协议\传输协议:定义了,客户端和服务器端通信时,发送数据的格式\特点:1\.基于TCP/IP的高级协议2\.默认端口号:803\.基于请求/响应模型的:一次请求对应一次响应4\.
Stella981 Stella981
3年前
Django基础一之web框架的本质
一web框架的本质及自定义web框架我们可以这样理解:所有的Web应用本质上就是一个socket服务端,而用户的浏览器就是一个socket客户端,基于请求做出响应,客户都先请求,服务端做出对应的响应,按照http协议的请求协议发送请求,服务端按照http协议的响应协议来响应请求,这样的网络通信,我们就可以自
Wesley13 Wesley13
3年前
PHP实现异步调用方法研究
浏览器和服务器之间是通过HTTP协议进行连接通讯的。这是一种基于请求和响应模型的协议。浏览器通过URL向服务器发起请求,Web服务器接收到请求,执行一段程序,然后做出响应,发送相应的html代码给客户端。这就有了一个问题,Web服务器执行一段程序,可能几毫秒就完成,也可能几分钟都完不成。如果程序执行缓慢,用户可能没有耐心等下去,就关闭浏览器了
LogicCascade
LogicCascade
Lv1
会当凌绝顶,一览众山小。
文章
4
粉丝
0
获赞
0