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) {
}
@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();
}
private void userLeave(WebSocket conn){
WsPool.removeUser(conn);
}
private void userJoin(WebSocket conn,String userName){
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>();
public static String getUserByWs(WebSocket conn) {
return wsUserMap.get(conn);
}
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);
}
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;
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class HNLWApplication
{
public static void main(String[] args)
{
ConfigurableApplicationContext run = SpringApplication.run(HNLWApplication.class, args);
System.out.println("(????)ノ゙ SpringBoot项目启动成功 ?(′?`?)゙ ");
MyWebScoket.setApplicationContext(run);
WebSocketImpl.DEBUG = false;
MyWebScoket s;
s = new MyWebScoket(8888);
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);
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') {
wx.sendSocketMessage({
data: "{\"name\":\"000001\"}"
})
}
},
定义的数据及调用的方法都有截图
三、演示流程
1、后台启动 2、微信小程序端启动建立链接
3、模拟后台向客户端发送信息 这里模拟我就在后台写了一个接口去向客户端发送请求代码很简单 一个post请求向客户端发送 这里使用的000001是小程序端建立链接时发送过去的唯一标识 推荐使用openId 我这里只是demo实例 4、客户端收到
到此为止就完成了 java后端使用到的类和pom 微信端的小程序代码 也都上传到网盘了 可以下载了看一下 链接: https://pan.baidu.com/s/1dLGB8Jto8dVcjGD9Ar50nA 提取码: 6qr5
如果有哪里描述不清楚可以留言 看到后会 即使更改为更容易理解的方式给更多人!
|