【websocket系列】uniapp-springboot-websocket整合

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

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
Spring Boot是一个开源的Java框架,用于开发基于Java的企业级应用程序。它提供了简化的配置和一些内置功能,使开发人员可以更快速地构建可靠的应用程序。 Netty是一个基于Java的异步事件驱动的网络应用程序框架,它被广泛应用于开发高性能的网络服务器和客户端。通过使用Netty,开发人员可以轻松地编写可扩展的高性能的网络应用程序。 WebSocket是一种在Web浏览器和服务器之间进行全双工通信的协议。它允许服务器主动向客户端发送消息,并且这些消息可以是文本或二进制数据。在开发实时应用程序时,WebSocket是一个非常有用的协议。 Socket是一种用于在计算机网络上进行通信的编程接口。它允许不同的计算机之间建立连接,并通过互相发送数据来进行交互。Socket在开发网络应用程序时起到了关键的作用,它使得应用程序能够通过网络传输数据。 UniApp是一个基于Vue.js的跨平台开发框架,开发人员可以使用UniApp编写一套代码,然后通过编译器将其转换为iOS、Android和Web等不同平台的应用程序。UniApp的目标是提供一种简单和高效的方式,让开发人员可以同时开发多个平台的应用程序。 综上所述,Spring Boot是一个Java框架,Netty是一个用于开发高性能网络应用程序的框架,WebSocket是一种实现全双工通信的协议,Socket是一种用于网络通信的编程接口,UniApp是一个跨平台开发框架。这些技术和工具可以一起使用,开发人员可以利用它们构建高效、可扩展的应用程序。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值