初识websocket及java服务端的简单实现

keepfighting!      2022-05-11     310

关键词:

概念:WebSocket是一种在单个TCP连接上进行全双工通信的协议。

WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输

背景:很多网站为了实现推送技术,所用的技术都是轮询。轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP请求,然后由服务器返回最新的数据给客户端的浏览器。这种传统的模式带来很明显的缺点,即浏览器需要不断的向服务器发出请求,然而HTTP请求可能包含较长的头部,其中真正有效的数据可能只是很小的一部分,显然这样会浪费很多的带宽等资源。

而比较新的技术去做轮询的效果是Comet。这种技术虽然可以双向通信,但依然需要反复发出请求。而且在Comet中,普遍采用的长链接,也会消耗服务器资源。

在这种情况下,HTML5定义了WebSocket协议,能更好的节省服务器资源和带宽,并且能够更实时地进行通讯。

websocket运用场景:

  1. 即时通讯:多媒体聊天,你可以使用该技术开个聊天室,聊个火热。可以单独2人聊个畅快。
  2. 互动游戏:现在多人游戏越来越火热,那么多人游戏必须是时时的,不考虑其他因素,只是时效性方面,也可以用该技术做多人游戏。
  3. 协同合作:开发人员会有git,svn等代码管理工具,但还是会有冲突。用此技术开发一个文档协同编辑工具,使每个人的编辑内容都时时同步,将不会有冲突发生。
  4. 动态数据表报:类似通知变更,如有需求,可以开发一个时时的数据报表,使用此技术,服务端数据发生变化,可在表报上立刻显示出来。如,电商平台的交易数据,每时每刻都在变化着,可以时时监控。
  5. 实时工具:如导航,实时查询工具等也可使用。

原理

WebSocket并不是全新的协议,而是利用了HTTP协议来建立连接。我们来看看WebSocket连接是如何创建的。

首先,WebSocket连接必须由浏览器发起,因为请求协议是一个标准的HTTP请求,格式如下:

GET ws://localhost:3000/ws/chat HTTP/1.1
Host: localhost
Upgrade: websocket
Connection: Upgrade
Origin: http://localhost:3000
Sec-WebSocket-Key: client-random-string
Sec-WebSocket-Version: 13

该请求和普通的HTTP请求有几点不同:

  1. GET请求的地址不是类似/path/,而是以ws://开头的地址;
  2. 请求头Upgrade: websocket和Connection: Upgrade表示这个连接将要被转换为WebSocket连接;
  3. Sec-WebSocket-Key是用于标识这个连接,并非用于加密数据;
  4. Sec-WebSocket-Version指定了WebSocket的协议版本。

随后,服务器如果接受该请求,就会返回如下响应:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: server-random-string

该响应代码101表示本次连接的HTTP协议即将被更改,更改后的协议就是Upgrade: websocket指定的WebSocket协议。

为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)

版本号和子协议规定了双方能理解的数据格式,以及是否支持压缩等等。如果仅使用WebSocket的API,就不需要关心这些。

现在,一个WebSocket连接就建立成功,浏览器和服务器就可以随时主动发送消息给对方。消息有两种,一种是文本,一种是二进制数据。通常,我们可以发送JSON格式的文本,这样,在浏览器处理起来就十分容易。

为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。

HTTP协议与websocket协议对比:

 

WebSocket目前支持两种统一资源标志符ws和wss,类似于HTTP和HTTPS。

 

浏览器支持:

很显然,要支持WebSocket通信,浏览器得支持这个协议,这样才能发出ws://xxx的请求。目前,支持WebSocket的主流浏览器如下:

  • Chrome
  • Firefox
  • IE >= 10
  • Sarafi >= 6
  • Android >= 4.4
  • iOS >= 8

 

客户端简单实现:

新建websocket.html

 

<!DOCTYPE HTML>
<html>
   <head>
   <meta charset="utf-8">
   <title>websocket 客户端</title>
    
      <script type="text/javascript">
         function WebSocketTest()
         {
            if ("WebSocket" in window)
            {
               alert("您的浏览器支持 WebSocket!");
               
               // 创建一个 websocket
               var ws = new WebSocket("ws://localhost:8887");
                
               ws.onopen = function()
               {
                  // Web Socket 已连接上,使用 send() 方法发送数据
                  ws.send("发送数据");
                  alert("数据发送中...");
               };
                
               ws.onmessage = function (evt) 
               { 
                  var received_msg = evt.data;
                  alert("数据已接收...");
               };
                
               ws.onclose = function()
               { 
                  // 关闭 websocket
                  alert("连接已关闭..."); 
               };
            }
            
            else
            {
               // 浏览器不支持 WebSocket
               alert("您的浏览器不支持 WebSocket!");
            }
         }
      </script>
        
   </head>
   <body>
   
      <div id="sse">
         <a href="javascript:WebSocketTest()">运行 WebSocket</a>
      </div>
      
   </body>
</html>

 

 

客户端API:

WebSocket 属性

以下是 WebSocket 对象的属性。假定我们使用了以上代码创建了 Socket 对象:

属性

描述

Socket.readyState

只读属性 readyState 表示连接状态,可以是以下值:

0 - 表示连接尚未建立。

1 - 表示连接已建立,可以进行通信。

2 - 表示连接正在进行关闭。

3 - 表示连接已经关闭或者连接不能打开。

Socket.bufferedAmount

只读属性 bufferedAmount 已被 send() 放入正在队列中等待传输,但是还没有发出的 UTF-8 文本字节数。

WebSocket 事件

以下是 WebSocket 对象的相关事件。假定我们使用了以上代码创建了 Socket 对象:

事件

事件处理程序

描述

open

Socket.onopen

连接建立时触发

message

Socket.onmessage

客户端接收服务端数据时触发

error

Socket.onerror

通信发生错误时触发

close

Socket.onclose

连接关闭时触发

WebSocket 方法

以下是 WebSocket 对象的相关方法。假定我们使用了以上代码创建了 Socket 对象:

方法

描述

Socket.send()

使用连接发送数据

Socket.close()

关闭连接

 

JAVA 服务端实现:

maven依赖

<dependency>
  <groupId>org.java-websocket</groupId>
  <artifactId>Java-WebSocket</artifactId>
  <version>1.4.0</version>
</dependency>

  

 

服务端示例:ServerDemo.java

import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;

import java.net.InetSocketAddress;
import java.net.UnknownHostException;

/**
 * @Author 99514925@qq.com
 * @Create 2020/2/3 23:03
 **/
public class ServerDemo extends WebSocketServer {


    public ServerDemo() throws UnknownHostException {
    }

    public ServerDemo(int port) throws UnknownHostException {
        super(new InetSocketAddress(port));
        System.out.println("websocket Server start at port:"+port);
    }


    /**
     * 触发连接事件
     */
    @Override
    public void onOpen(WebSocket conn, ClientHandshake clientHandshake) {
        System.out.println("new connection ===" + conn.getRemoteSocketAddress().getAddress().getHostAddress());
    }

    /**
     *
     * 连接断开时触发关闭事件
     */
    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {

    }

    /**
     * 客户端发送消息到服务器时触发事件
     */
    @Override
    public void onMessage(WebSocket conn, String message) {
        System.out.println("you have a new message: "+ message);
        //向客户端发送消息
        conn.send(message);
    }

    /**
     * 触发异常事件
     */
    @Override
    public void onError(WebSocket conn, Exception e) {
        //e.printStackTrace();
        if( conn != null ) {
            //some errors like port binding failed may not be assignable to a specific websocket
        }
    }

    /**
     * 启动服务端
     * @param args
     * @throws UnknownHostException
     */
    public static void main(String[] args) throws UnknownHostException {
        new ServerDemo(8887).start();
    }
}

 

 

由于WebSocket是一个协议,服务器具体怎么实现,取决于所用编程语言和框架本身。

 

springboot-websocket实现及原理

本文章包括websocket面试相关问题以及springboot如何整合webSocket。参考文档https://blog.csdn.net/prayallforyou/article/details/53737901、https://www.cnblogs.com/bianzy/p/5822426.html  webSocket是HTML5的一种新协议,它实现了服务端与客户端的全双工通信,... 查看详情

websocket简单实现(代码片段)

...连接的情况,服务端处理http请求往往占用大量资源,而websocket则能使web端和服务端维持长连接。除此之外,建立长连接亦可以使服务端主动向web端推送消息,从而为项目提供更加丰富的功能。本文面向初次使用go开发web服务端的... 查看详情

websocket通信实现java模拟一个client与webclient通信

...IDE是IDEA2017项目功能描述:启动项目,会启动一个web端的websocket-client和一个java模拟的websocket-server。项目中另外还有一个Main类,单独启动,会模拟启动一个java端的websocket-client。java-client可以发消息,通过server即时将消息推送到we... 查看详情

初识signalr(代码片段)

SIgnalR是微软开发的一套通信组件,如果听说过websocket的话,那么SignalR功能和websocket类似,提供客户端和服务端的实时通信。SignalR客户端可用于.net平台和js上,服务端(afaik)是在.net上的。对于js和服务器间的通信,signalR相较于... 查看详情

websocket实践——java实现websocket的两种方式

什么是WebSocket?   随着互联网的发展,传统的HTTP协议已经很难满足Web应用日益复杂的需求了。近年来,随着HTML5的诞生,WebSocket协议被提出,它实现了浏览器与服务器的全双工通信,扩展了浏览器与服务端的通信功能,使服... 查看详情

Java WebSocket:如何在不编写客户端的情况下测试服务器 WebSocket 端点 [关闭]

】JavaWebSocket:如何在不编写客户端的情况下测试服务器WebSocket端点[关闭]【英文标题】:JavaWebSocket:HowcanItestaServerWebSocketendpointwithoutwritingaclient[closed]【发布时间】:2019-09-2105:15:20【问题描述】:我正在使用Glassfish服务器来托管使... 查看详情

ios初识uitableview及简单用法

////ViewController.m//ZQRTableViewTest////Createdbyzzqqrron17/8/24.//Copyright(c)2017年zzqqrr.Allrightsreserved.//#import"ViewController.h"@interfaceViewController()<UITableViewDataSource>@proper 查看详情

websocket+sockjs+stompjs详解及实例(代码片段)

最近有项目需求要用到websocket,刚开始以为很简单,但是随着遇到问题,深入了解,才知道websocket并不是想象中的那么简单,这篇文章主要是考虑websocket在客户端的使用。1.http与websockethttp超文本传输协议,大家都非常熟悉,http有... 查看详情

websocket的简单实现

参考技术AWebSocket协议是基于TCP的一种新的网络协议。浏览器通信通常是基于HTTP协议,为什么还需要另一个协议?因为http只能由客户端发起,不能由服务端发起。而WebSocket浏览器和服务器只需要完成一次握手,两者之间就直接可... 查看详情

php简单实现websocket(demo)(代码片段)

WebSocket是HTML5开始提供的一种在单个TCP连接上进行全双工通讯的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocketAPI中,浏览器和服务器只需要完成一次握手的动作,... 查看详情

java怎么实现与websocket服务器的通信

java怎么实现与websocket服务器的通信。可有偿。要求:使用java语言能打通通信通道即可。不要找网上例子,例子没用。我大约可支付软妹币100的样子。websocket服务器的通信可以用tomcat-api来实现的,以前做过一个简单的推送示例,2227... 查看详情

websocket与redis结合,和客户端交互及统计在线人数的实现(代码片段)

前提实现对客户端的在线统计,及与客户端的交互和接受redis的消息设置spring上下文importorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAwar 查看详情

ios初识uitableview及简单用法二(模型数据)

////ViewController.m//ZQRTableViewTest////Createdbyzzqqrron17/8/24.//Copyright(c)2017年zzqqrr.Allrightsreserved.//#import"ViewController.h"#import"ZQRCarGroup.h"@interfaceViewController()<UITableVie 查看详情

html和websocket初识

一、web框架  众所周知,对于所有的Web应用,本质上其实就是一个socket服务端,用户的浏览器其实就是一个socket客户端。importsocketdefhandle_request(client):buf=client.recv(1024)client.send(b"HTTP/1.1200OK ")client.send(b"Hello,Bigberg")defmain() 查看详情

websocket的简单使用

WebSocket一种在单个TCP连接上进行全双工通讯的协议。WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端直接向客户端推送数据而不需要客户端进行请求,在WebSocketAPI中,浏览器和服务器只需要完成... 查看详情

springboot+vue+websocket实现服务器端向客户端主动发送消息

...文通过一个实际的场景来介绍在前后端分离的项目中通过WebSocket来实现服务器端主动向客户端发送消息的应用。主要内容如下Websocket是一种在单个TCP连接上进行全双工通信的协议。WebSocket连接成功后,服务端与客户端可以双向通... 查看详情

http协议理解及服务端与客户端的设计实现(代码片段)

HTTP协议理解及服务端与客户端的设计实现版权声明:转载必须注明本文转自严振杰的博客:http://blog.yanzhenjie.com本文主要帮助读者理解HTTP的协作原理、HTTP相关的各层协议,在服务端和客户端的架构设计和一些优化的技巧&#... 查看详情

springboot整合websocket实现即时聊天功能

参考技术A近期,公司需要新增即时聊天的业务,于是用websocket整合到Springboot完成业务的实现。一、我们来简单的介绍下websocket的交互原理:1.客户端先服务端发起websocket请求;2.服务端接收到请求之后,把请求响应返回给客户端... 查看详情