uniapp
这里不需要导入什么依赖
直接使用uniapp自带的就可以了
参考文档:https://developers.weixin.qq.com/miniprogram/dev/api/network/websocket/wx.sendSocketMessage.html
<template>
<view class="warp">
<!--这里我是直接想获得mq传过来的信息,所以我就没有做太多的处理了,直接进入页面的时候连接websocket-->
</template>
<script>
export default {
data() {
return {
socketTask: null,
// 确保websocket是打开状态
is_open_socket: false
};
},
onLoad: function() {
this.connectSocketInit();
},
methods: {
// 进入这个页面的时候创建websocket连接【整个页面随时使用】
connectSocketInit() {
// 创建一个this.socketTask对象【发送、接收、关闭socket都由这个对象操作】
//这个有区别于angular angular是对象操作的,有点类似于angular的new WebSocket()
this.socketTask = uni.connectSocket({
// 【非常重要】必须确保你的服务器是成功的,记得后端不能进行拦截
url: "ws://192.168.101.141:4433/imserver/app/"+uni.getStorageSync("token"),
success(data) {
console.log("websocket连接成功");
},
});
// 消息的发送和接收必须在正常连接打开中,才能发送或接收【否则会失败】
//连接成功时回调
this.socketTask.onOpen((res) => {
console.log("WebSocket连接正常打开中...!");
this.is_open_socket = true;
//发送信息
this.socketTask.send({
data: "uni-app发送一条消息",
async success() {
console.log("消息发送成功");
},
});
//收到信息的回调
this.socketTask.onMessage((res) => {
console.log("收到服务器内容:" + res.data);
});
})
// 这里仅是事件监听【如果socket关闭了会执行】
this.socketTask.onClose(() => {
console.log("已经被关闭了")
})
//发送方法的话,主要使用send()方法,可以参考一下uniapp文档
},
// 关闭websocket【离开这个页面的时候执行关闭】
closeSocket() {
this.socketTask.close({
success(res) {
this.is_open_socket = false;
console.log("关闭成功", res)
},
fail(err) {
console.log("关闭失败", err)
}
})
},
// 关闭websocket【必须在实例销毁之前关闭,否则会是underfined错误】
beforeDestroy() {
this.closeSocket();
},
}
</script>
<style>
</style>
springboot
1、导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
<scope>compile</scope>
</dependency>
2、配置文件:主要是用来支持websocket
package com.fusdom.webSocket;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
/**
* 开启WebSocket支持
* @author zhengkai
*/
//@Configuration注解
@Configuration
public class WebSocketConfig {
//@Bean注解
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
3、!!! 对接口不能进行拦截
大家的拦截器有很多不同的用法,我们是在application.properties进行处理的,大家可以找个自己处理拦截的地方,不然访问接口时会给拦截
然后拦截的问题要怎么处理?? 这个我是在成功访问之后在WebSocketServer.java种的onOpen方法处理
4、WebSocketServerApp
这个方法类似于我们的controller 层,主要用于与前端之间的交互
package com.fusdom.webSocket;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.fusdom.config.JWTConfig;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
//这个是客户端访问的接口
@ServerEndpoint("/imserver/app/{token}")
@Component
public class WebSocketServerApp {
//日志
static Log log= LogFactory.get(WebSocketServerApp.class);
/**静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。*/
private static int onlineCount = 0;
/**concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。*/
//新建一个ConcurrentHashMap webSocketMap 用于接收当前userId的WebSocket,方便IM之间对userId进行推送消息。
private static ConcurrentHashMap<String,WebSocketServerApp> webSocketMap = new ConcurrentHashMap<>();
/**与某个客户端的连接会话,需要通过它来给客户端发送数据*/
private Session session;
// /**接收userId*/
private String userId="";
public static Session temp;
public static boolean flag=false;
/**
* 连接建立成功调用的方法*/
@OnOpen
public void onOpen(Session session, @PathParam("token") String token) {
//去掉token前缀
String afterToken = token.replace(JWTConfig.wxtokenPrefix, "");
//解析JWT
Claims claims = Jwts.parser()
//设置解析秘钥
.setSigningKey(JWTConfig.wxsecret)
//解析token
.parseClaimsJws(afterToken)
.getBody();
if(claims!=null){
//获取到session和userId
this.session = session;
this.userId= claims.getId().toString();
this.temp=session;
flag=true;
//如果userId存在,则移除,再添加一个相同的userId和新的Session(防止session过期)
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
webSocketMap.put(userId,this);
//加入set中
}else{
webSocketMap.put(userId,this);
//加入set中
addOnlineCount();
//在线数加1
}
log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());
try {
sendMessage(this.userId+"连接成功");
} catch (IOException e) {
log.error("用户:"+userId+",网络异常!!!!!!");
}
}else{
log.error("用户:"+userId+",没有权限!!!!!!");
}
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
//如果存在userId则移除,然后人数-1
if(webSocketMap.containsKey(userId)){
webSocketMap.remove(userId);
//从set中删除
subOnlineCount();
flag=false;
}
log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
}
/**
*
* @param session
* @param error
*/
@OnError
public void onError(Session session, Throwable error) {
log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
error.printStackTrace();
}
/**
* 实现服务器主动推送
*/
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
/**
* 发送自定义消息
* */
public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
log.info("发送消息到:"+userId+",报文:"+message);
if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
webSocketMap.get(userId).sendMessage(message);
}else{
log.error("用户"+userId+",不在线!");
}
}
public static synchronized int getOnlineCount() {
return onlineCount;
}
public static synchronized void addOnlineCount() {
WebSocketServerApp.onlineCount++;
}
public static synchronized void subOnlineCount() {
WebSocketServerApp.onlineCount--;
}
public void setSession(Session session) {
this.session = session;
}
}
参考文章:https://blog.csdn.net/a873744779/article/details/102694679?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161179455616780269871952%252522%25252C%2
52522scm%252522%25253A%25252220140713.130102334…%252522%25257D&request_id=161179455616780269871952&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allbaidu_landing_v2~default-1-102694679.first_rank_v2_pc_rank_v29&utm_term=uniapp%25E5%25AE%259E%25E7%258E%25B0websocket