WebSocket

WebSocket协议

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信,即允许服务器主动发送信息给客户端。因此,在WebSocket中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输,客户端和服务器之间的数据交换变得更加简单。

为什么需要websocket?

websocket是和http并存的两种协议。

HTTP协议有一个缺陷:通信只能由客户端发起。HTTP协议做不到服务器主动向客户端推送信息。

这种单向请求的特点,注定了如果服务器有连续的状态变化,客户端要获知就非常麻烦。我们只能使用"轮询":每隔一段时候,就发出一个询问,了解服务器有没有新的信息。

轮询的效率低,非常浪费资源(因为必须不停连接,或者 HTTP 连接始终打开)。因此,工程师们一直在思考,有没有更好的方法。WebSocket 就是这样发明的。

什么是websocket?

WebSocket是HTML5规范提出的一种协议;他是一种协议,万变不离其宗,也是基于TCP协议的;和HTTP协议是并存的两种协议。

websocket 和 http 的区别:

1、WebSocket是双向通信协议,模拟Socket协议,可以双向发送或接受信息,而HTTP是单向的;

2、WebSocket是需要浏览器和服务器握手进行建立连接的,而http是浏览器发起向服务器的连接。

WebSocket是HTML5中的协议。HTML5 Web Sockets规范定义了Web Sockets API,支持页面使用Web Socket协议与远程主机进行全双工的通信。它引入了WebSocket接口并且定义了一个全双工的通信通道,通过一个单一的套接字在Web上进行操作。

HTML5 Web Sockets以最小的开销高效地提供了Web连接。相较于经常需要使用推送实时数据到客户端甚至通过维护两个HTTP连接来模拟全双工连接的旧的轮询或长轮询(Comet)来说,这就极大的减少了不必要的网络流量与延迟。

要使用HTML5 Web Sockets从一个Web客户端连接到一个远程端点,你要创建一个新的WebSocket实例并为之提供一个URL来表示你想要连接到的远程端点。

该规范定义了ws://以及wss://模式来分别表示WebSocket和安全WebSocket连接,这就跟http:// 以及https:// 的区别是差不多的。

一个WebSocket连接是在客户端与服务器之间HTTP协议的初始握手阶段将其升级到Web Socket协议来建立的,其底层仍是TCP/IP连接。

websocket 和 socket 的关系
  1. Socket其实并不是一个协议,而是为了方便使用TCP或UDP而抽象出来的一层,是位于应用层和传输控制层之间的一组接口。

“Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口,提供一套调用TCP/IP协议的API。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。”

当两台主机通信时,必须通过Socket连接,Socket则利用TCP/IP协议建立TCP连接。TCP连接则更依靠于底层的IP协议,IP协议的连接则依赖于链路层等更低层次。

WebSocket就像HTTP一样,则是一个典型的应用层协议。

Socket是传输控制层接口,WebSocket是应用层协议。

websocket 的优势

现在,很多网站为了实现推送技术,所用的技术都是Ajax轮询。轮询是在特定的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。

Ajax : "Asynchronous Javascript And XML”(异步JavaScript和XML)

Ajax能够在不刷新整个页面的情况下,跟后端的服务器进行通信,从而获得当前页面请求的某些内容,然后对页面进行部分更新。因为一张网页的大部分地方在加载之后是不需要更新的,这种方式减少了很多没有意义的数据传输,可以提高效率,也能提升用户体验。一句话概括,Ajax能完成的就是一件事,进行更有效的前后端数据交互。

从具体的实现上来说,现代的浏览器通过一个JavaScript的内置对象,也就是出现频率很高的XMLHttpRequest对象来实现这种效果。

这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求。然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

HTML5定义的WebSocket协议优势如下:

  • 小Header:互相沟通的Header非常小,只有2Bytes左右。

  • 服务器不再被动接收到浏览器的请求之后才返回数据,而是在有新数据时就主动推送给浏览器。

  • WebSocket协议能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

websocket 的特点

websocket最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种。

其他特点包括:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

websocket Client API

1. WebSocket Constructor

var ws = new WebSocket('ws://localhost:8080');

客户端与服务器进行连接。

2. webSocket.readyState

readyState属性返回实例对象的当前状态,共有四种。

  • CONNECTING:值为0,表示正在连接。
  • OPEN:值为1,表示连接成功,可以通信了。
  • CLOSING:值为2,表示连接正在关闭。
  • CLOSED:值为3,表示连接已经关闭,或者打开连接失败。

3. webSocket.onopen

实例对象的onopen属性,用于指定连接成功后的回调函数。

4. webSocket.onclose

实例对象的onclose属性,用于指定连接关闭后的回调函数。

5. webSocket.onmessage

实例对象的onmessage属性,用于指定收到服务器数据后的回调函数。

6. webSocket.send()

实例对象的send()方法用于向服务器发送数据。

7. webSocket.onerror

实例对象的onerror属性,用于指定报错时的回调函数。

Django Channels Tutorial

Channels是Django团队研发的一个给Django提供websocket支持的框架,Channels 允许您在 Django 站点中使用 Websockets 和其他非 HTTP 协议。例如, 您可能希望 Websockets 允许网站上的页面立即从 Django 服务器接收更新, 而无需使用 HTTP 长轮询或其他昂贵的技术。使用channels可以让Django应用拥有实时通讯和给用户主动推送信息的功能。

在Django项目里面,我们并不是直接使用websocket协议,因为原生django不支持websocket,仅有Django Channels库支持WebSocket。

Channels由几个包组成:

  • Channels, Django集成层
  • Daphne, HTTP和WebSocket终端服务器
  • ASGIref,基于ASGI库
  • channel_redis, Redis通道层后端(可选)

在本教程中, 我们将建立一个简单的聊天服务器, 在那里你可以加入一个在线房间, 张贴消息到房间, 并让其他人在同一房间看到这些消息立即。

Tutorial Part 1: 基本设置

在本教程中, 我们将构建一个简单的聊天服务器。它将有两个页面:

  • index 视图,用于输入要加入的聊天室的名称。
  • room 视图,可以查看在特定聊天室中发送的消息。
    • room 视图将使用 WebSocket 与 Django 服务器进行通信, 并监听任何发送出来的消息。

假设您已经熟悉构建django站点的基本概念:

  1. 假设您已经安装了Django,通过在shell提示符下运行以下命令来查看您安装的Django版本(3.2.8):

    $ python3 -m django --version
  2. 假设您已经安装了channels,通过在shell提示符下运行以下命令来查看您安装的Channels版本(3.0.4):

    $ python3 -c 'import channels; print(channels.__version__)'

1. 创建一个项目

$ django-admin startproject mysite

这将在当前目录中创建一个 mysite 目录, 其中有以下内容:

mysite/
manage.py
mysite/
__init__.py
asgi.py
settings.py
urls.py
wsgi.py

2. 创建聊天应用

我们将聊天服务器的代码放在其自己的应用程序中。确保您与manage.py位于同一目录中,然后键入以下命令:

$ python3 manage.py startapp chat

这将创建一个目录chat,其布局如下:

chat/
__init__.py
admin.py
apps.py
migrations/
__init__.py
models.py
tests.py
views.py

我们需要告诉我们的项目,该应用程序已安装。编辑文件mysite/mysite/settings.py并添加chatINSTALLED_APPS设置。它看起来像这样:

# mysite/settings.py
INSTALLED_APPS = [
'chat',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

3. 添加index视图

chat 目录中创建 templates 目录。在刚刚创建的 templates 目录中, 创建另一个名为 chat 的目录, 并在其中创建一个名为 index.html 的文件。

将以下代码放入:chat/templates/chat/index.html

<!-- chat/templates/chat/index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Chat Rooms</title>
</head>
<body>
What chat room would you like to enter?<br>
<input id="room-name-input" type="text" size="100"><br>
<input id="room-name-submit" type="button" value="Enter">
<script>
document.querySelector('#room-name-input').focus();
document.querySelector('#room-name-input').onkeyup = function(e) {
if (e.keyCode === 13) { // enter, return
document.querySelector('#room-name-submit').click();
}
};
document.querySelector('#room-name-submit').onclick = function(e) {
var roomName = document.querySelector('#room-name-input').value;
window.location.pathname = '/chat/' + roomName + '/';
};
</script>
</body>
</html>

4.为index视图创建视图函数

将以下代码放入chat/views.py

# chat/views.py
from django.shortcuts import render
def index(request):
return render(request, 'chat/index.html')

要调用视图,我们需要将其映射到 URL - 为此,我们需要一个 URLconf。

5. 在chat目录下创建URLconf

要在chat目录中创建 URLconf,请创建一个名为urls.py的文件。文件中包含以下代码:

# chat/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]

Tutorial Part 2:实现聊天服务器

Tutorial Part 3:将聊天服务器重写为异步

Tutorial Part 4:自动化测试

posted on   SocialistYouth  阅读(239)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人

统计

点击右上角即可分享
微信分享提示