SpringBoot2.x集成WebSocket,实现后台向前端(h5 页面,java客户端)推送信息

目录

SpringBoot 集成WebSocket,实现后台向前端(h5 页面,java客户端)推送

什么是WebSocket?

概念:

特点:

通讯方式

服务器端代码实现

maven依赖

websocket的configuration配置文件

websocket 的发布实现:

H5客户端实现

maven依赖

aplication.properties 的系统配置文件配置

页面代码(重点)

java客户端代码

maven依赖

service 接口

service 实现

controller 接口调用

websocket 的configuration配置文件


SpringBoot 集成WebSocket,实现后台向前端(h5 页面,java客户端)推送

ps:如果你们觉得写得还不错,请给我一个大大的赞

什么是WebSocket?

概念:

webSocket是H5的新协议,基于tcp协议,实现浏览器与客户端的双工通信。解决了http协议只能由客户端向服务发送请求的弊端,替代长轮询节省带宽和资源。(多于见聊天室)

特点:

(1)服务端可以主动推送信息,属于服务器推送技术的一种。

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

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

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

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

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

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

通讯方式

websocket 和 http 通讯的区别

了解了websocket的运行方式之后,直接撸代码吧!!!

服务器端代码实现

maven依赖

由于本人使用的是springboot 2.1.6.RELEASE,它很好的兼容了websocket,因此不需要指定websocket的版本号,只要把依赖引入进来就可以了。

  <!-- websocket-->
   <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
   </dependency>

websocket的configuration配置文件

@Bean
public ServerEndpointExporter serverEndpointExporter() {
    return new ServerEndpointExporter();
}

websocket 的发布实现:

package com.along.websocket.server;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/websocket")
@Component
public class WebSocketServer {


    private  static final Logger log = LoggerFactory.getLogger(WebSocketServer.class);

    /** 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
    private static int onlineCount = 0;

    /** concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
    private static CopyOnWriteArraySet<WebSocketServer> webSocketSet = new CopyOnWriteArraySet<>();

    /** 与某个客户端的连接会话,需要通过它来给客户端发送数据 */
    private Session session;

    /** 接收sid */
    private String sid="";

    /** 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("cid") String sid) {
        this.session = session;
        //加入set中
        webSocketSet.add(this);
        //在线数加1
        addOnlineCount();
        log.info("有新窗口开始监听:"+sid+",当前在线人数为" + getOnlineCount());
        this.sid=sid;
        try {
            sendMessage("连接成功",sid);
        } catch (IOException e) {
            log.error("websocket IO异常");
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        //从set中删除
        webSocketSet.remove(this);
        //在线数减1
        subOnlineCount();
        log.info("有一连接关闭!当前在线人数为" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session,@PathParam("cid") String sid) {
        log.info("收到来自窗口"+sid+"的信息:"+message);
        //群发消息
        for (WebSocketServer item : webSocketSet) {
            try {
                item.sendMessage(message,sid);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error,@PathParam("cid") String sid) {
        log.error("发生错误");
        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message,String sid) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }


    /**
     * 群发自定义消息
     * */
    public static void sendInfo(String message, String sid) throws IOException {
        log.info("推送消息到窗口"+sid+",推送内容:"+message);
        for (WebSocketServer item : webSocketSet) {
            try {
                //这里可以设定只推送给这个sid的,为null则全部推送
                if(sid==null) {
                    item.sendMessage(message,sid);
                }else if(item.sid.equals(sid)){
                    item.sendMessage(message,sid);
                }
            } catch (IOException e) {
                continue;
            }
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }


}

这样就实现了websocket 的服务器端,是不是很简单,下面就实现h5 调用

H5客户端实现

我想通过调用接口,然后跳转到我们的客户端h5页面,通过界面按钮发送消息给服务器,然后服务器在发送消息给其他客户端(迷你版的聊天服务器)

maven依赖

 <!-- thymeleaf 页面模板-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

aplication.properties 的系统配置文件配置

spring.thymeleaf.prefix=classpath:/template/    

页面代码(重点)
 

<!DOCTYPE HTML>
<html>
<head>
    <title>My WebSocket</title>
</head>

<body>
<h2>Welcome ,<p th:text="${cid}"></p></h2>
<input id="text" type="text"/>
<button onclick="send()">Send</button>
<button onclick="closeWebSocket()">Close</button>
<div id="message">
</div>
</body>

<script type="text/javascript">
    var websocket = null;

    //判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        websocket = new WebSocket("ws://localhost:10080/websocket");
    } else {
        alert('Not support websocket')
    }

    //连接发生错误的回调方法
    websocket.onerror = function () {
        setMessageInnerHTML("error");
    };

    //连接成功建立的回调方法
    websocket.onopen = function (event) {
        setMessageInnerHTML("open");
    }

    //接收到消息的回调方法
    websocket.onmessage = function (event) {
        setMessageInnerHTML(event.data);
    }

    //连接关闭的回调方法
    websocket.onclose = function () {
        setMessageInnerHTML("close");
    }

    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
        websocket.close();
    }

    //将消息显示在网页上
    function setMessageInnerHTML(innerHTML) {
        document.getElementById('message').innerHTML += innerHTML + '<br/>';
    }

    //关闭连接
    function closeWebSocket() {
        websocket.close();
    }

    //发送消息
    function send() {
        var message = document.getElementById('text').value;
        websocket.send(message);
        document.getElementById('text').value = '';
    }
</script>
</html>

java客户端代码

maven依赖

<!--websocket作为客户端-->
     <dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.5</version>
        </dependency>

service 接口

/**
     * 群发
     * @param message
     */
    void groupSending(String message);

    /**
     * 指定发送
     * @param name
     * @param message
     */
    void appointSending(String name,String message);

service 实现

package com.along.websocketclient.service.impl;

import com.along.websocketclient.service.WebSocketService;
import org.java_websocket.client.WebSocketClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class WebScoketServiceImpl implements WebSocketService {

    @Autowired
    private WebSocketClient webSocketClient;


    @Override
    public void groupSending(String message) {
        // 这里我加了初生牛犊,江湖再见-- 是因为我在index.html页面中,要拆分用户编号和消息的标识,只是一个例子而已
        // 在index.html会随机生成用户编号,这里相当于模拟页面发送消息
        // 实际这样写就行了 webSocketClient.send(message)
        webSocketClient.send(message + "---初生牛犊,江湖再见");

    }

    @Override
    public void appointSending(String name, String message) {
        // 这里指定发送的规则由服务端决定参数格式
        webSocketClient.send("TOUSER" + name + ";" + message);
    }
}

controller 接口调用

package com.along.websocketclient.controller;

import com.along.websocketclient.service.WebSocketService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

@RestController
@RequestMapping("/websocket")
public class IndexController {

    @Resource
    private WebSocketService webSocketService;

    @GetMapping("/sendMessage")
    public String sendMessage(String message){
        webSocketService.groupSending(message);
        return message;
    }

}

websocket 的configuration配置文件

package com.along.websocketclient.config;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_6455;
import org.java_websocket.handshake.ServerHandshake;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.net.URI;

@Configuration
public class WebSocketConfig {

    private static final Logger log = LoggerFactory.getLogger(WebSocketConfig.class);

    @Bean
    public WebSocketClient webSocketClient() {
        try {
            //websocket 发送地址
            WebSocketClient webSocketClient = new WebSocketClient(new URI("ws://localhost:10080/websocket"), new Draft_6455()) {
                @Override
                public void onOpen(ServerHandshake handshakedata) {
                    log.info("[websocket] 连接成功");
                }

                @Override
                public void onMessage(String message) {
                    log.info("[websocket] 收到消息={}", message);

                }

                @Override
                public void onClose(int code, String reason, boolean remote) {
                    log.info("[websocket] 退出连接");
                }

                @Override
                public void onError(Exception ex) {
                    log.info("[websocket] 连接错误={}", ex.getMessage());
                }
            };
            webSocketClient.connect();
            return webSocketClient;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

socket客户端的配置文件已经完成。

如果你还是不会弄,请到下载源码,我只是想单纯让你们下载,需要使用的积分是系统自动匹配的,我不能改变,有需要的就去下载源码,但上面教程讲的比别的任何博客都清楚了。

java 实现二维码、在二维码上面增加logo,二维码下方或者上方增加文字

java项目中使用ffmpeg剪辑部分视频

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
org.java_websocket是一个Java语言实现WebSocket协议库,它提供了WebSocket客户端服务器端的功能。通过使用org.java_websocket库,你可以轻松地创建WebSocket客户端来与WebSocket服务器进行通信。 要使用org.java_websocket实现WebSocket客户端,你需要进行以下步骤: 1. 导入org.java_websocket库:首先,你需要将org.java_websocket库添加到你的Java项目中。你可以通过在项目的构建文件(如Maven或Gradle)中添加相应的依赖来实现。 2. 创建WebSocket客户端对象:使用org.java_websocket库,你可以创建一个WebSocketClient对象来表示WebSocket客户端。你需要提供WebSocket服务器的URL作为参数来初始化WebSocketClient对象。 3. 实现WebSocketClient的回调方法:WebSocketClient类提供了一些回调方法,用于处理与WebSocket服务器的连接、消息接收和错误处理等。你需要扩展WebSocketClient类,并重写这些回调方法来实现自定义的逻辑。 4. 连接到WebSocket服务器:通过调用WebSocketClient对象的connect()方法,你可以连接到WebSocket服务器。 5. 发送和接收消息:一旦连接建立,你可以使用WebSocketClient对象的send()方法发送消息到服务器,并通过重写onMessage()方法来处理从服务器接收到的消息。 下面是一个简单的示例代码,演示了如何使用org.java_websocket实现WebSocket客户端: ```java import org.java_websocket.client.WebSocketClient; import org.java_websocket.handshake.ServerHandshake; import java.net.URI; import java.net.URISyntaxException; public class MyWebSocketClient extends WebSocketClient { public MyWebSocketClient(String serverUrl) throws URISyntaxException { super(new URI(serverUrl)); } @Override public void onOpen(ServerHandshake handshakedata) { System.out.println("Connected to WebSocket server"); } @Override public void onMessage(String message) { System.out.println("Received message: " + message); } @Override public void onClose(int code, String reason, boolean remote) { System.out.println("Disconnected from WebSocket server"); } @Override public void onError(Exception ex) { System.err.println("WebSocket error: " + ex.getMessage()); } public static void main(String[] args) { try { MyWebSocketClient client = new MyWebSocketClient("ws://localhost:8080/websocket"); client.connect(); } catch (URISyntaxException e) { e.printStackTrace(); } } } ``` 在上面的示例中,我们创建了一个名为MyWebSocketClient的类,它扩展了WebSocketClient类,并重写了一些回调方法。在main()方法中,我们创建了一个MyWebSocketClient对象,并通过调用connect()方法连接到WebSocket服务器。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值