webSocket教程-程序员宅基地

技术标签: 网络  websocket  网络协议  网络通信  

本教程从webSocket是什么及特点webSocket的应用webSocket原理webSocket案例实现、注意点五个部分来讲解webSocket的入门到实际使用

一、webSocket是什么及特点?

1、webSocket是一种在单个TCP连接上进行全双工通信协议,即数据可以同时双向传输;

2、WebSocket是一种持久化网络通信协议,一次握手即可建立长连接(握手使用HTTP协议,所以不容易被屏蔽,能通过各种HTTP代理服务器),与HTTP协议不同,HTTP需要三次握手,并且无状态,即每次通信请求都是唯一的,通过session、cookie配对等方式来认识每次请求;

3、WebSocket可以实现服务器主动推送数据给客户端,即可以做到服务器端与客户端的实时通信,与HTTP协议不同,HTTP需要每次客户端发给请求,服务器端才会给出响应,不过基于HTTP也可实现实时通信技术,例如:轮询、长轮询、流化技术(不过有弊端);

4、可以发送文本二进制数据,数据格式比较轻量,性能开销小;

5、不受同源策略限制,因此不必理会跨域问题;

6、与HTTP协议一样有着良好的兼容性,默认端口是80和443。

二、WebSocket的应用

webSocket的最显著的应用特点就是实时,像常见的微信、QQ聊天室,股票基金走势等等,这些注重于实时数据的接收与发送都可以使用webSocket。

三、WebSocket原理

WebSocket协议请求

 在发送HTTP请求的请求头中:

1. Connection和Upgrade字段会告诉服务器,客户端要对协议升级,升级成为WenSocket协议。

2. Sec-WebSocket-Key是一个Base64编码值,是由浏览器随机生成。

3. Sec-WebSocket-Version表示客户端所使用的协议版本。

在响应头中:

1. Connection字段表示协议已经升级。

2. Sec-WebSocket-Accept表明服务器接受了客户端的请求。

3. Upgrade字段表示协议升级成为了WenSocket协议。

四、webSocket案例实现

1、单一客户端与服务端之间的实时通信(实现在客户端发送给服务端数据后,服务端接收响应数据后,无需客户端再次发起请求,直接将数据发送给客户端)

下面的案例只是将客户端接收到服务器端的信息直接输出到了控制台,并没有做精美的页面来展示服务端消息。

使用node创建本地服务器

服务器端代码:

var Websocket = require('websocket').server
var http = require('http')
//监听8080端口,服务器启动时控制台输出,因为websocket第一次请求需要走HTTP协议,所以创建HTTP服务器
var httpServer = http.createServer().listen(8080, function(){
    console.log('http://127.0.0.1:8080');
})
//创建Websocket实例
var wsServer = new Websocket({
    httpServer: httpServer,
    autoAcceptConnections: false
})
//监听请求
wsServer.on('request', function(request){
    // request.accept()是拿到wsServer链接实例
    var connection = request.accept()
    // 监听到达服务器的消息事件
    connection.on('message', function(msg){
        //当有数据到达服务器即使用send()API向客户端发出数据
        connection.send(msg)
    })
})

客户端代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<input type="text" id="text">
<input type="button" value="发送" onclick="send()" ></input>
    <script>
        //与服务器建立连接
        var websocket = new WebSocket('ws://127.0.0.1:8080')
        console.log(websocket.readyState);
        // readyState是当前websocket实例状态: 
                    //0链接还没有建立(正在建立连接)
                    // 1链接建立成功
                    // 2链接正在关闭
                    // 3链接已经关闭
        //websocket.onopen被触发的时候事件
        websocket.onopen = function(){
            console.log(websocket.readyState);
        }
        //点击发送给服务端发出数据,也是使用send()API发出数据
        function send(){
            var text = document.getElementById('text').value
            websocket.send(text)
        }
        // 监听服务器推送事件(当服务器有消息发送过来即在控制台输出数据,在这里可以直观的看见,
        //客户端没有给服务器端发出请求,但当服务器端接收到消息后就主动给客户端发出了数据)
        websocket.onmessage = function(back){
            console.log(back.data);
            console.log(back);
        }
    </script>
</body>
</html>

2、多个客户端与服务端之间的实时通信(实现在一个客户端发送给服务端数据后,服务端接收响应数据后,无需客户端再次发起请求,直接将数据发送给当前所有客户端,类似群聊功能)

在实现聊天室的案例里,只是将每一个websocket链接实例放进数组,再使用for循环向对应的客户端发送数据.看到这里我们可以小小的猜测一下为什么聊天软件的群聊为什么都有人数限制了?

服务器端代码:

var Websocket = require('websocket').server
var http = require('http')

var httpServer = http.createServer().listen(8080, function(){
    console.log('http://127.0.0.1:8080');
})
var wsServer = new Websocket({
    httpServer: httpServer,
    autoAcceptConnections: false
})
var connectionArr = []
// 服务端向多个客户端群发消息
wsServer.on('request', function(request){
    // request.accept()是拿到wsServer链接实例
    var connection = request.accept()
    //将所有wsServer链接实例放进数组,即形成链接池
    connectionArr.push(connection)
    // 监听到达服务器的消息事件
    connection.on('message', function(msg){
        //使用for循环实现链接池中的每一个链接向对应客户端发出消息
        for(var i = 0;i<connectionArr.length;i++){
            connectionArr[i].send(msg.utf8Data)
        }
    })
})

客户端代码与第一个案例无异:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <input type="text" id="text">
    <input type="button" value="发送" onclick="send()" ></input>
    <script>
        var websocket = new WebSocket('ws://127.0.0.1:8080')
        websocket.onopen = function(){
            console.log(websocket.readyState);
        }
        function send(){
            var text = document.getElementById('text').value
            websocket.send(text)
        }
        // 监听服务器推送事件
        websocket.onmessage = function(back){
            console.log(back.data);
            console.log(back);
        }
    </script>
</body>
</html>

五、注意点:浏览器每次刷新都会新建一个websocket链接实例。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_46045382/article/details/126141079

智能推荐

Linux GVim插件配置-程序员宅基地

文章浏览阅读6.6k次。Vim编辑器被称为“编辑器之神“,是Linux系统中最常用的两个文本编辑器之一(另一个是被称为“神之编辑器”的Emacs)。GVim是图形化的Vim,很多版本的Linux都将GVim作为系统的一部分预装在客户端,但是最原始的GVim界面简单,功能都需要通过命令来实现,无形中提高了学习Vim的难度。虽然Vim入门较难,但是能够一直作为Linux常用文本编辑器之一,主要取决于它的可定制性。除了通过_linux gvim插件

深度学习之视频人脸识别系列三:人脸表征_深度学习对人脸识别的推动-程序员宅基地

文章浏览阅读2.2k次。作者 |东田应子本文是深度学习之视频人脸识别系列的第三篇文章,介绍人脸表征相关算法和论文综述。在本系列第一篇文章里我们介绍了人脸识别领域的一些基本概念,分析了深度学习在人脸识别的基本流程,并总结了近年来科研领域的研究进展,最后分析了静态数据与视频动态数据在人脸识别技术上的差异;在第二篇文章中介绍了人脸检测与对齐的相关算法。一、人脸表征把人脸图像通过神经网络,得到一个特定维..._深度学习对人脸识别的推动

arm-linux-gcc的总结_gcc -pthread -o-程序员宅基地

文章浏览阅读1.4k次。关于arm-linux-gcc的总结,本文基于SC2440开发板。来源是《嵌入式完全开发手册》以及博客文章,在此基础上添加补充,也包含个人理解所总结而来的,可能有部分错误,欢迎指正_gcc -pthread -o

Outlook的收件箱等名称显示不正常的修正方法-程序员宅基地

文章浏览阅读394次。问:我现在有一个EXCHANGE帐号,以前用中文版的outlook来收过邮件,现在用英文版的outlook来收发邮件,这时碰到一个麻烦的问题,用中文版的时候,邮件默认是收到“收件箱”当中的,现在改用英文版的outlook收信后,以前的“收件箱”变成了“???”,另外还多了一个“inbox"收件夹,(中英文的文件夹同时存在,另外,日历,联系人都变成了双份的了,..._outlook为什么有的邮箱显示不同的邮件名

c语言中ANSI标准的关键字,C语言中32个关键字详解-程序员宅基地

文章浏览阅读2k次,点赞3次,收藏16次。C语言中32个关键字详解由 ANSI 标准定义的 C 语言关键字共32个,根据关键字的作用,可以将关键字分为数据类型关键字和流程控制关键字两大类。一、数据类型关键字A 基本数据类型(5个)void:声明函数无返回值或无参数,声明无类型指针,显示丢弃去处结果char:字符型类型数据,属于整型数据的一种int:整型数据,通常为编译器指定的机器字长float:单精度浮点数据,属于浮点数据的一种doubl..._ansi c32个关键字的意思

使用Eclipse RCP进行桌面程序开发(三):视图和透视图_eclipse rcp 打开透视图-程序员宅基地

文章浏览阅读1.6k次。使用Eclipse RCP进行桌面程序开发(一):快速起步 使用Eclipse RCP进行桌面程序开发(二):菜单、工具栏和对话框 Eclipse RCP开发中,和用户进行交互最多的界面,应该是视图了,而透视图就是将已有的视图、菜单、工具栏、编辑器等等进行组合和布局。看完这一节,我们就可以建立如下图这样的程序界面了。首先我们来介绍一下视图,建立一个视图其实非常简_eclipse rcp 打开透视图

随便推点

gojs拖动窗口缩放后自动居中对齐-程序员宅基地

文章浏览阅读627次。gojs拖动窗口缩放后自动居中对齐

用MyEclipse Struts Editor编辑器编辑Struts的配置文件错误处理_is not configured as a myeclipse web-struts projec-程序员宅基地

文章浏览阅读858次。用MyEclipse Struts Editor编辑器编辑Struts的配置文件的时候,出现如下错误: “Project abc is not configured as a MyEclipse Web-Struts Project. Therefore the MyEclipse Struts Editor may not be used with struts-config.xml. Th_is not configured as a myeclipse web-struts project. therefore the myeclipse

网页自动加拼音html,HTML5给汉字加拼音收起展开组件的实现代码-程序员宅基地

文章浏览阅读486次。来看看 HTML 的历史和规范常识。HTML 规范是 W3C 与 WHATWG 合作共同产出的,HTML5 因此也不例外。其中:W3C 指 World Wide Web ConsortiumWHATWG 指 Web Hypertext Application Technology Working Group说好听了是“合作产出”,但其实更像是“HTML5 有两套规范”。但话说天下大势合久必分,分久..._网页加注音

numpy.meshgrid()绘制网格图_numpy 画背景网格-程序员宅基地

文章浏览阅读3.1k次,点赞3次,收藏5次。一、numpy.meshgrid()介绍1.1、numpy.meshgrid()的用途    numpy.meshgrid()——生成网格点坐标矩阵。1.2、什么是 “网格点” 和 “坐标矩阵”    上图中,每个交叉点都是网格点,描述这些网格点的坐标的矩阵,就是坐标矩阵。    图中 A,B,C,D,E,FA,B,C,D,E,FA,B,C,D,E,F 是 6 个网格点,如何用矩阵形式(坐标矩阵)来批量描述这些点的坐标呢?答案如下:X=[012012] X = \begin{bmatrix}_numpy 画背景网格

简单的文本编辑器 - wxWindows编程事例_wxwindows使用-程序员宅基地

文章浏览阅读2.2k次。 上一次简单介绍了一下wxWindows,那么今天就写个简单的程序,来体验一下wxWindows强大的功能。下面我们来创建一个简单的文本编辑器。你看了后会发现用wxWindows编写程序原来是这么的简单。废话少说,开始创建简单文本编辑器。 创建自己的MainFrame// 文件: MainFrm.h#ifndef _MainFrm_H#define _Mai_wxwindows使用

vue项目引入外部字体使用_vue项目如何用字体库-程序员宅基地

文章浏览阅读196次。发现一个字体库,里面字体还挺好看的。_vue项目如何用字体库

推荐文章

热门文章

相关标签