栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

从零开始,SpringBoot搭建WebSocket

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从零开始,SpringBoot搭建WebSocket

一 什么是WebSocket 1.1 首先分清几个概念
  • **http协议:**超文本传输协议,属于应用层。它的任务是与服务器交换信息。至于怎么连接到服务器,怎么保证数据正确,http不管。

  • **TCP协议:**传输控制协议,属于传输层。任务是保证连接的可靠,包括防止丢失,出错。所以在初次连接的时候进行3次握手,断开连接时进行4次挥手。至于连接上以后具体传送什么数据,tcp不管。

PS:别的应用层协议也能通过tcp进行,那么这协议在底层也进行三次握手。

1.2 混淆点
  • WebSocket:基于TCP的,运行在应用层,替代http的一个协议。
  • 网上说的WebSocket只有一次握手,指的是:客户端发送一个http请求到服务器,服务器响应后标志这个连接建立起来。而不是指TCP的三次握手。
1.3 优点
  • 节约宽带。轮询服务端数据的方式,使用的是http协议,head的信息很大,有效数据占比低,而使用WebSocket,头信息很小,有效数据占比高。
  • 无浪费。轮询方法可能轮询10次,才可能碰到服务端数据更新,那么前9次数据都浪费了。而WebSocket是由服务器主动发回,来的都是新数据。
  • 实时性。当服务器完成协议升级后(HTTP->Websocket),服务端可以主动向客户端推送信息,省去了客户端发起请求的步骤,同时没有间隔时间,只要服务端内容有变化,就可以告知客户端。实时性大大提高。
二 Socket和WebSocket的区别
  • 本质上:

    • Socket本身不是一个协议,而是一个调用接口(API),它工作在OSI模型中的会话层(第5层),是对TCP/IP协议的封装。websocket运行在应用层,是http升级的一个协议。

  • 连接:

    • Socket连接需要一对套接字,一个运行于客户端,另一个运行于服务端。连接分为三个步骤:服务器监听,客户端请求,连接确认。

    • websocket在客户端,发送一个http请求到服务器,当服务器响应后,完成协议升级,连接建立。

三 WebSocket服务端搭建 3.1 导入jar包

            org.springframework.boot
            spring-boot-starter-websocket

3.2 搭建websocket服务
  • WebSocketConfig

    package com.wyq.websocket.config;
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.socket.server.standard.ServerEndpointExporter;
    
    
    @Configuration
    public class WebSocketConfig {
        
        @Bean
        public ServerEndpointExporter serverEndpointExporter(){
            return new ServerEndpointExporter();
        }
    }
    
    
  • WebSocketServer

    用于接收客户端的webSocket请求,处理主要逻辑。代码如下:

    • @ServerEndpoint注解中写上客户端连接的地址。
    package com.wyq.websocket.component;
    
    import cn.hutool.json.JSONObject;
    import org.springframework.stereotype.Component;
    
    import javax.websocket.*;
    import javax.websocket.server.PathParam;
    import javax.websocket.server.ServerEndpoint;
    import java.io.IOException;
    import java.util.Map;
    import java.util.concurrent.ConcurrentHashMap;
    
    
    @Component
    @ServerEndpoint("/webSocket/{username}")
    public class WebSocketServer {
        
        private static Map clients = new ConcurrentHashMap<>();
    
        
        @OnOpen
        public void onOpen(@PathParam("username") String username, Session session) throws IOException {
            if (username == null) {
                return;
            }
            clients.put(username, session);
            System.out.println("用户:" + username + "已连接到websocke服务器");
        }
    
        
        @OnClose
        public void onClose(@PathParam("username") String username) throws IOException {
            clients.remove(username);
            System.out.println("用户:" + username + "已离开websocket服务器");
        }
    
        
        @OnMessage
        public void onMessage(String json) throws IOException {
            System.out.println("前端发送的信息为:" + json);
            JSONObject jsonObject = new JSONObject(json);
            String user = jsonObject.getStr("user");
            String msg = jsonObject.getStr("msg");
            Session session = clients.get(user);
            //如果这个好友在线就直接发给他
            if (session != null) {
                sendMessageTo(msg,session);
            } else {
                System.out.println("对方不在线,对方名字为:" + user);
            }
        }
    
        
        @OnError
        public void onError(Session session, Throwable error) {
            error.printStackTrace();
        }
    
        
        public void sendMessageTo(String message, Session session) throws IOException {
            session.getBasicRemote().sendText(message);
        }
    }
    
3.3 第三方网站测试
  • 在线测试网址

    http://www.websocket-test.com/

  • 连接url

    ws://localhost:8080/webSocket/小王

  • 建立、断开连接测试

  • 模拟小王和小李通信

    • 小王给小李发

      {“msg”:“你好,我是小王”,“user”:“小李”}

    • 小李收到后给小王发

      {“msg”:“你好你好,我是小李”,“user”:“小王”}

    • 小王页面显示

    • 小李页面显示

四 客户端搭建 4.1 html页面

index.html




    
    
    客户端
    


用户小王


链接状态:

未建立链接

给用户小李发送信息:

从服务器发来的信息:

4.2 js配置

index.js

var websocket = null;

var host = document.location.host;

var username = "${loginUsername}"; // 获得当前登录人员的userName

// alert(username)

//判断当前浏览器是否支持WebSocket
if ('WebSocket' in window) {
    alert("浏览器支持Websocket")
    //假设当前用户是小王
    username = "小王";
    //alert(username);
    //alert('ws://'+host+'/webSocket/'+username);
} else {
    alert('当前浏览器 Not support websocket')
}


//将消息显示在网页上
function setMessageInnerHTML(innerHTML) {
    document.getElementById('message').innerHTML += innerHTML + '
'; } //建立websocket链接 function buttonCreate() { try { websocket = new WebSocket('ws://' + host + '/webSocket/' + username); initWebSocket(); }catch (e){ alert(e); } } //关闭websocket链接 function buttonClose() { try{ websocket.close(); }catch (e){ alert(e) } } function initWebSocket() { //连接发生错误的回调方法 websocket.onerror = function() { //alert("WebSocket连接发生错误") setMessageInnerHTML("WebSocket连接发生错误"); }; //连接成功建立的回调方法 websocket.onopen = function() { //alert("WebSocket连接成功") changeStatus("WebSocket连接成功"); } //接收到消息的回调方法 websocket.onmessage = function(event) { //alert("这是后台推送的消息:"+event.data); setMessageInnerHTML(event.data); } //连接关闭的回调方法 websocket.onclose = function() { changeStatus("WebSocket连接关闭"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function() { try { websocket.close(); }catch (e){ alert(e); } } } function changeStatus(text) { document.getElementById("status").innerText = text; }
4.3 controller模拟信息发送

ServerController.java

package com.wyq.websocket.controller;

import cn.hutool.json.JSONObject;
import com.wyq.websocket.component.WebSocketServer;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;


@RestController
public class ServerController {
    @RequestMapping(value = "/server", method = {RequestMethod.POST, RequestMethod.GET})
    public void server(HttpServletRequest request) throws IOException {
        try {
            String msg = request.getParameter("msg");
            String user = request.getParameter("user");
            //获取用户的webSocket对象
            WebSocketServer ws = new WebSocketServer();
            //封装JSON
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("user", user);
            jsonObject.put("msg", msg);
            String message = jsonObject.toString();
            //发送消息
            ws.onMessage(message);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
    }
}

4.4 运行测试
  • 小王界面

  • 小李界面

    五 源码下载

    github源码下载地址:

    https://github.com/Ricardo0324/SpringBoot-WebSocket-Demo

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/872878.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号