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。

通讯方式

SpringBoot2.x集成WebSocket,实现后台向前端(h5 页面,java客户端)推送信息_第1张图片 websocket 和 http 通讯的区别

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

服务器端代码实现

maven依赖

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

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

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 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依赖

 
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

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

spring.thymeleaf.prefix=classpath:/template/    

页面代码(重点)
 




    My WebSocket



Welcome ,

java客户端代码

maven依赖


     
            org.java-websocket
            Java-WebSocket
            1.3.5
        

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剪辑部分视频

你可能感兴趣的:(javaweb,springboot,websocket,服务器端,客户端,推送消息)