PC端WebSocket springboot stompjs 简单的实现即时通讯

tech2024-06-19  65

websocket介绍: WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端

websocket使用场景分享 如弹幕,网页聊天系统,实时监控,股票行情推送等

效果图: 一,简单地访问8080端口:

二,点击v1 test.html 和index.html连接:

三、v2连接:、 四、v3连接: ’ 五、v4: 六、v5连接: 代码: pom.xml

<?xml version="1.0" encoding="UTF-8"?>

4.0.0

<groupId>org.example</groupId> <artifactId>websocket_shy</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.9.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>webjars-locator</artifactId> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>sockjs-client</artifactId> <version>1.0.2</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>stomp-websocket</artifactId> <version>2.3.3</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.7</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <properties> <java.version>1.8</java.version> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>

一、model包下:(类似实体类,有两个类)

package cn.shy.model;

import java.util.Date;

/**

@program: websocket_shy

@description: 类似实体类1

@author: hylshyshm

@create: 2020-09-03 16:02 **/ public class InMessage { private String from; private String to; private String content; private Date time;

public InMessage(){

} public InMessage(String content){ this.content=content; } public String getFrom() { return from; }

public void setFrom(String from) { this.from = from; }

public String getTo() { return to; }

public void setTo(String to) { this.to = to; }

public String getContent() { return content; }

public void setContent(String content) { this.content = content; }

public Date getTime() { return time; }

public void setTime(Date time) { this.time = time; }

}


package cn.shy.model;

import java.util.Date;

/**

@program: websocket_shy

@description: 类似实体类2

@author: hylshyshm

@create: 2020-09-03 16:04 **/ public class OutMessage { private String from; private String content; private Date time = new Date(); public OutMessage(){

} public OutMessage(String content){ this.content=content; } public String getFrom() { return from; }

public void setFrom(String from) { this.from = from; }

public String getContent() { return content; }

public void setContent(String content) { this.content = content; }

public Date getTime() { return time; }

public void setTime(Date time) { this.time = time; } }

二、配置类:config package cn.shy.config;

import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry;

/**

@program: websocket_shy

@description: 配置类

@author: hylshyshm

@create: 2020-09-03 16:09 **/ @Configuration @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {

/**

注册端点,发布或者订阅消息的时候需要连接此端点setAllowedOrigins 非必须,*表示允许其他域进行连接withSockJS 表示开始sockejs支持addInterceptors 添加拦截器 / @Override public void registerStompEndpoints(StompEndpointRegistry stompEndpointRegistry) { stompEndpointRegistry.addEndpoint("/endpoint-websocket").setAllowedOrigins("").withSockJS(); stompEndpointRegistry.addEndpoint("/endpoint-websocket").addInterceptors();

}

/**

配置消息代理(中介)

enableSimpleBroker 服务端推送给客户端的路径前缀

setApplicationDestinationPrefixes 客户端发送数据给服务器端的一个前缀 */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) {

registry.enableSimpleBroker("/topic", “/chat”); registry.setApplicationDestinationPrefixes("/app");

} }

三、listener监听器类:2个 package cn.shy.listener;

import org.springframework.context.ApplicationListener; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.stereotype.Component; import org.springframework.web.socket.messaging.SessionConnectEvent;

/**

@program: websocket_shy@description: 监听事件类型1@author: hylshyshm@create: 2020-09-03 16:13 **/ @Component public class ConnetEventListent implements ApplicationListener { @Override public void onApplicationEvent(SessionConnectEvent sessionConnectEvent) { StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(sessionConnectEvent.getMessage()); //System.out.println("【sessionConnectedEvent:监听事件类型:】"+headerAccessor.getCommand().getMessageType()); } }

package cn.shy.listener;

import org.springframework.context.ApplicationListener; import org.springframework.messaging.simp.stomp.StompHeaderAccessor; import org.springframework.stereotype.Component; import org.springframework.web.socket.messaging.SessionSubscribeEvent;

/**

@program: websocket_shy

@description: 监听事件类型2

@author: hylshyshm

@create: 2020-09-03 16:19 **/ @Component public class SubSribeEventListent implements ApplicationListener { @Override public void onApplicationEvent(SessionSubscribeEvent sessionSubscribeEvent) { StompHeaderAccessor headerAccessor = StompHeaderAccessor.wrap(sessionSubscribeEvent.getMessage()); //System.out.println(“sessionSubscribeEvent【监听事件类型:】”+headerAccessor.getCommand().getMessageType()+headerAccessor.getMessage());

} }

四、controller控制器: v1: package cn.shy.controller.v1;

import cn.shy.model.InMessage; import cn.shy.model.OutMessage; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller;

/**

@program: websocket_shy

@description: v1版本控制器

@author: hylshyshm

@create: 2020-09-03 16:24 **/ @Controller public class GameInfoController { @MessageMapping("/v1/chat") @SendTo("/topic/game_chat") public OutMessage gameInfo(InMessage inMessage){

return new OutMessage(inMessage.getContent());

} }


v5: package cn.shy.controller.v5;

import cn.shy.service.WebSocketService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Controller;

/**

@program: websocket_shy

@description: v5控制器

@author: hylshyshm

@create: 2020-09-03 17:46 **/ @Controller public class V5RoomController { @Autowired private WebSocketService webSocketService;

//@MessageMapping("/v4/schedule/push") @Scheduled(fixedRate = 3000) public void fuqInfo(){ webSocketService.sendMessageCPUInfo(); } }


SampleController: package cn.shy.controller;

import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;

@Controller

public class SampleController {

@RequestMapping("/") @ResponseBody String home() { return "Hello World!"; }

}

五、service:业务层

package cn.shy.service;

import cn.shy.model.InMessage; import cn.shy.model.OutMessage; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.messaging.simp.SimpMessagingTemplate; import org.springframework.stereotype.Service;

/**

@program: websocket_shy

@description: 业务层

@author: hylshyshm

@create: 2020-09-03 16:27 **/ @Service public class WebSocketService { @Autowired private SimpMessagingTemplate simpMessagingTemplate;

//对应v2的控制器–但v2控制器可以不要–注意在app.js中sendName()方法 是公用一个 …send("/app/v1/chat"… public void sendTopicMessage(String desc, InMessage inMessage){ simpMessagingTemplate.convertAndSend(desc,new OutMessage(inMessage.getContent())); }

//对应v3的控制器–但v3控制器可以不要 public void sendSingleMessage(InMessage inMessage){ simpMessagingTemplate.convertAndSend("/chat/single/"+inMessage.getTo(), new OutMessage(inMessage.getFrom()+" 发送:"+ inMessage.getContent())); }

//对应v4的控制器–但v4控制器可以不要 public void sendSingleOneMessage(InMessage inMessage){ simpMessagingTemplate.convertAndSendToUser(inMessage.getTo(),"/chat/single",new OutMessage(inMessage.getFrom()+" 发送:"+ inMessage.getContent())); }

//对应v5的控制器 public void sendMessageCPUInfo(){ int pro = Runtime.getRuntime().availableProcessors(); long freeCpu =Runtime.getRuntime().freeMemory(); long maxCpu = Runtime.getRuntime().maxMemory();

String message =String.format("服务器可用处理器:%s,虚拟机可用内存大小:%s,已经内存大小:%s",pro,freeCpu,maxCpu); simpMessagingTemplate.convertAndSend("/topic/cpu_info",new OutMessage(message));

}

}

六、启动类: import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.scheduling.annotation.EnableScheduling;

/**

@program: websocket_shy@description: 开始启动类@author: hylshyshm@create: 2020-09-03 16:06 **/ @ComponentScan(basePackages = “cn.shy”) @SpringBootApplication @EnableScheduling class startAppliction { public static void main(String args[]){ SpringApplication.run(startAppliction.class,args); } }

上面实现了后端代码: 如下属于前端代码:在resource下创建构建多层目录 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200903212200680.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5bHNoeXNobQ==,size_16,color_FFFFFF,t_70#pic_center 与v1 v2 v3 v4 v5 处于同一级目录的 app.js: var stompClient = null;

function setConnected(connected) { $("#connect").prop(“disabled”, connected); $("#disconnect").prop(“disabled”, !connected); if (connected) { $("#conversation").show(); } else { $("#conversation").hide(); } $("#notice").html(""); }

function connect() { var socket = new SockJS(’/endpoint-websocket’); //连接上端点(基站)

stompClient = Stomp.over(socket); //用stom进行包装,规范协议 stompClient.connect({}, function (frame) { setConnected(true); //console.log('Connected: ' + frame); stompClient.subscribe('/topic/game_chat', function (result) { //v5/app.js与其他的区别在这里! //console.info(result) showContent(JSON.parse(result.body)); }); });

}

function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } setConnected(false); //console.log(“Disconnected”); }

function sendName() {

stompClient.send("/app/v1/chat", {}, JSON.stringify({'content': $("#content").val()}));

}

function showContent(body) { $("#notice").append("" + body.content + " “+new Date(body.time).toLocaleString()+”"); }

$(function () { $(“form”).on(‘submit’, function (e) { e.preventDefault(); }); $( “#connect” ).click(function() { connect(); }); $( “#disconnect” ).click(function() { disconnect(); }); $( “#send” ).click(function() { sendName(); }); });

同一级目录的main.css body { background-color: #f5f5f5; }

#main-content { max-width: 940px; padding: 2em 3em; margin: 0 auto 20px; background-color: #fff; border: 1px solid #e5e5e5; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; }

v1: index.html:

Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect 发布新公告 发布 游戏公告内容 ------- test.html: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20200903213643968.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2h5bHNoeXNobQ==,size_16,color_FFFFFF,t_70#pic_center) Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect 游戏公告内容

v2: index.html:

Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect 发布新公告 发布 王者游戏排行榜

v3: index.html:

Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect <input type="text" id="content" class="form-control" placeholder="请输入..."> </div> <button id="send" class="btn btn-default" type="submit">发送</button> </form> </div> </div> <div class="row"> <div class="col-md-12"> <table id="conversation" class="table table-striped"> <thead> <tr> <th>记录</th> </tr> </thead> <tbody id="notice"> </tbody> </table> </div> </div>

v4: index.html:

Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect <input type="text" id="content" class="form-control" placeholder="请输入..."> </div> <button id="send" class="btn btn-default" type="submit">发送</button> </form> </div> </div> <div class="row"> <div class="col-md-12"> <table id="conversation" class="table table-striped"> <thead> <tr> <th>记录</th> </tr> </thead> <tbody id="notice"> </tbody> </table> </div> </div>

v5: app.js: var stompClient = null;

function setConnected(connected) { $("#connect").prop(“disabled”, connected); $("#disconnect").prop(“disabled”, !connected); if (connected) { $("#conversation").show(); } else { $("#conversation").hide(); } $("#notice").html(""); }

function connect() { var socket = new SockJS(’/endpoint-websocket’); stompClient = Stomp.over(socket); stompClient.connect({}, function (frame) { setConnected(true); console.log(‘Connected: ’ + frame); stompClient.subscribe(’/topic/cpu_info’, function (result) { showContent(JSON.parse(result.body)); }); }); }

function disconnect() { if (stompClient !== null) { stompClient.disconnect(); } setConnected(false); console.log(“Disconnected”); }

function sendName() { stompClient.send("/app/v4/schedule/push", {}, JSON.stringify({‘content’: KaTeX parse error: Expected 'EOF', got '#' at position 3: ("#̲content").val()…("#to").val(), ‘from’😒("#from").val()})); }

function showContent(body) { $("#notice").prepend("" + body.content + " “+new Date(body.time).toLocaleString()+”"); }

$(function () { $(“form”).on(‘submit’, function (e) { e.preventDefault(); }); $( “#connect” ).click(function() { connect(); }); $( “#disconnect” ).click(function() { disconnect(); }); $( “#send” ).click(function() { sendName(); }); });


index.html:

Hello WebSocket

Seems your browser doesn't support Javascript! Websocket relies on Javascript being enabled. Please enable Javascript and reload this page!

建立连接通道: Connect Disconnect 记录
最新回复(0)