目录
SpringBoot 集成WebSocket,实现后台向前端(h5 页面,java客户端)推送
什么是WebSocket?
概念:
特点:
通讯方式
服务器端代码实现
maven依赖
websocket的configuration配置文件
websocket 的发布实现:
H5客户端实现
maven依赖
aplication.properties 的系统配置文件配置
页面代码(重点)
java客户端代码
maven依赖
service 接口
service 实现
controller 接口调用
websocket 的configuration配置文件
ps:如果你们觉得写得还不错,请给我一个大大的赞
webSocket是H5的新协议,基于tcp协议,实现浏览器与客户端的双工通信。解决了http协议只能由客户端向服务发送请求的弊端,替代长轮询节省带宽和资源。(多于见聊天室)
(1)服务端可以主动推送信息,属于服务器推送技术的一种。
(2)建立在TCP协议之上,服务端的实现比较容易。
(3)与HTTP协议有着良好的兼容性,默认端口也是80和443,并且握手阶段采用HTTP协议,因此握手时不容易屏蔽,能通过各种HTTP代理服务器。
(4)数据格式比较轻量,性能开销小,通信高效。
(5)可以发送文本,也可以发送二进制数据。
(6)没有同源限制,客户端可以与任意服务器通信。
(7)协议标识符是ws(如果加密,则为wss),服务器网址就是URL。
了解了websocket的运行方式之后,直接撸代码吧!!!
由于本人使用的是springboot 2.1.6.RELEASE,它很好的兼容了websocket,因此不需要指定websocket的版本号,只要把依赖引入进来就可以了。
org.springframework.boot
spring-boot-starter-websocket
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
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页面,通过界面按钮发送消息给服务器,然后服务器在发送消息给其他客户端(迷你版的聊天服务器)
org.springframework.boot
spring-boot-starter-thymeleaf
spring.thymeleaf.prefix=classpath:/template/
My WebSocket
Welcome ,
org.java-websocket
Java-WebSocket
1.3.5
/**
* 群发
* @param message
*/
void groupSending(String message);
/**
* 指定发送
* @param name
* @param message
*/
void appointSending(String name,String message);
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);
}
}
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;
}
}
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剪辑部分视频