IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> SpringBoot结合Websocket对微信小程序发送订单提示 !!! -> 正文阅读

[网络协议]SpringBoot结合Websocket对微信小程序发送订单提示 !!!

0.1 首先要知道小程序端使用条件

在这里插入图片描述

一、先说后java端代码

流程:
1、在pom引入webSocket所需包
2、后台编写websocket代码
3、微信小程序与后台进行交互代码

1、pom文件

		<!--	使用socket	-->
		<dependency>
			<groupId>org.java-websocket</groupId>
			<artifactId>Java-WebSocket</artifactId>
			<version>1.3.0</version>
		</dependency>

2.1、单独创建一个socket文件夹用与实现长链接的文件方便以后复制粘贴
再创建MyWebScoket.java

import com.alibaba.fastjson.JSONObject;
import org.java_websocket.WebSocket;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.server.WebSocketServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Map;

@Component
public class MyWebScoket extends WebSocketServer {

    @Autowired
    private WsPool wsPool;

    private static ApplicationContext applicationContext;

    public MyWebScoket() throws UnknownHostException {
    }

    public MyWebScoket(int port)  {
        super(new InetSocketAddress(port));
    }

    public MyWebScoket(InetSocketAddress address) {
        super(address);
    }

    public static void setApplicationContext(ApplicationContext applicationContext){
        MyWebScoket.applicationContext = applicationContext;
    }

    @Override
    public void onOpen(WebSocket conn, ClientHandshake handshake) {
        // ws连接的时候触发的代码,onOpen中我们不做任何操作
    }

    @Override
    public void onClose(WebSocket conn, int code, String reason, boolean remote) {
        System.out.println("用户断开链接:");
        //断开连接时候触发代码
        userLeave(conn);
        System.out.println(reason);
        System.out.println("conn:"+conn);
        System.out.println("code:"+code);
        System.out.println("reason:"+reason);
        System.out.println("remote:"+remote);
    }

    @Override
    public void onMessage(WebSocket conn, String message) {
        //有用户连接进来
        Map<String, String> obj =  (Map<String,String>) JSONObject.parse(message);
        System.out.println(message);
        String username = obj.get("name");
        userJoin(conn,  username);
    }

    @Override
    public void onError(WebSocket conn, Exception ex) {
        //错误时候触发的代码
        System.out.println("on error");
        ex.printStackTrace();
    }

    /**
     * 去除掉失效的websocket链接
     */
    private void userLeave(WebSocket conn){
        WsPool.removeUser(conn);
    }
    /**
     * 将websocket加入用户池
     * @param conn
     * @param userName
     */
    private void userJoin(WebSocket conn,String userName){
    	//这里最为关键 使用spring的注入是行不通的只能走最原始的办法 
        WsPool wsPool =(WsPool) applicationContext.getBean("wsPool");
        wsPool.addUser(userName, conn);
    }

这里面的 setApplicationContext 方法作用特别大 解决了使用spring注入为null的问题

如果你使用的是SSM可以参考我的另一篇文章 SSM使用WebSocket进行依赖注入为null的解决办法

2.2 创建一个WsPool 基本上就是方便我们结合业务代码使用创建的

import org.java_websocket.WebSocket;
import org.springframework.stereotype.Component;

import java.util.*;

@Component
public class WsPool {

    private static final Map<WebSocket, String> wsUserMap = new HashMap<WebSocket, String>();

    /**
     * 通过websocket连接获取其对应的用户
     */
    public static String getUserByWs(WebSocket conn) {
        return wsUserMap.get(conn);
    }

    /**
     * 根据userName获取WebSocket,这是一个list,此处取第一个
     * 因为有可能多个websocket对应一个userName(但一般是只有一个,因为在close方法中,我们将失效的websocket连接去除了)
     */
    public WebSocket getWsByUser(String userName) {
        Set<WebSocket> keySet = wsUserMap.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String cuser = wsUserMap.get(conn);
                if (cuser.equals(userName)) {
                    return conn;
                }
            }
        }
        return null;
    }

    /**
     * 向连接池中添加连接
     */
    public  void addUser(String userName, WebSocket conn) {
        wsUserMap.put(conn, userName); // 添加连接
    }

    /**
     * 获取所有连接池中的用户,因为set是不允许重复的,所以可以得到无重复的user数组
     */
    public static Collection<String> getOnlineUser() {
        List<String> setUsers = new ArrayList<String>();
        Collection<String> setUser = wsUserMap.values();
        for (String u : setUser) {
            setUsers.add(u);
        }
        return setUsers;
    }

    /**
     * 移除连接池中的连接
     */
    public static boolean removeUser(WebSocket conn) {
        if (wsUserMap.containsKey(conn)) {
            wsUserMap.remove(conn); // 移除连接
            return true;
        } else {
            return false;
        }
    }

    /**
     * 向特定的用户发送数据
     */
    public  void sendMessageToUser(WebSocket conn, String message) {
        String s = wsUserMap.get(conn);
        if (null != conn && null != s) {
            conn.send(message);
        }
    }

    /**
     * 向所有的用户发送消息
     */
    public static void sendMessageToAll(String message) {
        Set<WebSocket> keySet = wsUserMap.keySet();
        synchronized (keySet) {
            for (WebSocket conn : keySet) {
                String user = wsUserMap.get(conn);
                if (user != null) {
                    conn.send(message);
                }
            }
        }
    }

}

这里的WsPool类可以根据客户端请求的唯一标识进行存储和获取 以及对用户发送消息使用

2.3 最后一部我们的后端就完成了 就是设置启动服务的时候启动websocket和占用端口了
我们这里就不使用注解放在启动类里了 感兴趣的可以创建一个类把启动所需的东西放进去然后进行注解配置到springboot的启动类上面就行了

这里我就直接放到启动类里启动了


import com.hnlw.project.merchant.socket.config.MyWebScoket;
import org.java_websocket.WebSocketImpl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * 启动程序
 * 
 * @author hnlw
 */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class HNLWApplication
{
    public static void main(String[] args)
    {
        ConfigurableApplicationContext run = SpringApplication.run(HNLWApplication.class, args);
        System.out.println("(????)ノ゙   SpringBoot项目启动成功   ?(′?`?)゙  ");

		//这里特别关键的一步就是对前面2.1创建的MyWebScoket里面编写的setApplicationContext方法进行赋值,项目启动后就赋过去 后面可以直接拿到了
        MyWebScoket.setApplicationContext(run);
        WebSocketImpl.DEBUG = false;
        MyWebScoket s;
        s = new MyWebScoket(8888);//WebSocket 的占用端口可以更改为自己习惯的端口
        s.start();
        System.out.println("(????)ノ゙   WebSocket启动成功   ?(′?`?)゙  ");
    }
}

到此为止后端的就已经完成了,我们看一下微信小程序如何与后台进行交接

二、微信端比较简单
流程:进入页面或进入小程序就建立链接 我这里是结合项目需求进入某个页面时建立链接 也可以进入小程序时就建立链接需要再app.js里面配置一下就行 可以参考进入小程序创建链接 也可根据我下面的 加入到app.js就行

我这里在进入index.wxml 时就创建链接

在页面的js加入 这里的 openSocket 在进入页面触发一下就能建立链接了

这里使用 的 this.data.socketStatus 只是在data中定义了一个属性

openSocket() {
    //打开时的动作
     wx.onSocketOpen(() => {
       console.log('WebSocket 已连接')
       this.data.socketStatus = 'connected';
       this.sendMessage();
     })
     //断开时的动作
     wx.onSocketClose(() => {
       console.log('WebSocket 已断开')
       this.data.socketStatus = 'closed'
     })
     //报错时的动作
     wx.onSocketError(error => {
       console.error('socket error:', error)
     })
     // 监听服务器推送的消息
     wx.onSocketMessage(message => {
      console.log("message",message);
       //把JSONStr转为JSON
       message = message.data.replace(" ", "");
       if (typeof message != 'object') {
         message = message.replace(/\ufeff/g, ""); //重点
         var jj = JSON.parse(message);
         message = jj;
       }
       console.log("【websocket监听到消息】内容如下:");
       console.log(message);
     })
     // 打开信道
     wx.connectSocket({
       url: "ws://" + "192.168.0.105" + ":8888",
     })
   },
     
 //关闭信道
   closeSocket() {
     if (this.data.socketStatus === 'connected') {
       wx.closeSocket({
         success: () => {
           this.data.socketStatus = 'closed'
         }
       })
     }
   },
     
  //发送消息函数
   sendMessage() {
     if (this.data.socketStatus === 'connected') {
     //自定义的发给后台识别的参数 ,我这里发送的是name
       wx.sendSocketMessage({
         //data: "{\"name\":\"" + wx.getStorageSync('openid') + "\"}"  
         data: "{\"name\":\"000001\"}"
       })
     }
   },

定义的数据及调用的方法都有截图
在这里插入图片描述

三、演示流程

1、后台启动
2、微信小程序端启动建立链接
在这里插入图片描述

3、模拟后台向客户端发送信息
这里模拟我就在后台写了一个接口去向客户端发送请求代码很简单
一个post请求向客户端发送
在这里插入图片描述
在这里插入图片描述
这里使用的000001是小程序端建立链接时发送过去的唯一标识 推荐使用openId 我这里只是demo实例
4、客户端收到
在这里插入图片描述

到此为止就完成了
java后端使用到的类和pom 微信端的小程序代码 也都上传到网盘了 可以下载了看一下
链接: https://pan.baidu.com/s/1dLGB8Jto8dVcjGD9Ar50nA 提取码: 6qr5

如果有哪里描述不清楚可以留言 看到后会 即使更改为更容易理解的方式给更多人!

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-10 11:12:15  更:2021-09-10 11:14:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 2:01:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码