dead work:1.小程序wss需要准备ssl的证书(ps.可在阿里云免费申请)。
2.本地测试可通过花生壳内网映射也可以直接修改本机的hosts。
cause:websocket和阿里提供的mqtt一样都是通过长连接发送数据,可在后台直接转发,无须一个个提取。
main body:Spring 4.0为WebSocket通信提供了支持,WebSocket只是两个应用之间通信的通道。使用了WebSocket和STOMP实现消息功能,在WebSocket一端的应用发送消息,另外一端处理消息。因为它是全双工的,所以每一端都可以发送和处理消息,这就方便了小程序的数据接收。后台用了SpringBoot。
code:
initSocket: function() {
var that = this;
// socket是否连接
var socketConnected = false;
// 待发送的消息队列
var messageQueue = [];
// 是否断线重连
var reconnect = true;
function sendSocketMessage(msg) {
// console.log(msg);
// 如果socket已连接则发送消息
if (socketConnected) {
wx.sendSocketMessage({
data: msg
})
} else {
// socket没有连接将消息放入队列中
messageQueue.push(msg);
}
}
// 关闭连接
function close() {
if (socketConnected) {
wx.closeSocket()
}
}
var ws = {
send: sendSocketMessage,
close: close
}
// 创建一个 WebSocket 连接
function connect() {
wx.connectSocket({
url: 'wss://xxxxxxxx'
})
}
connect();
// 监听 WebSocket 连接打开事件
wx.onSocketOpen(function (res) {
console.log("WebSocket 连接成功")
socketConnected = true;
ws.onopen();
// 连接成功后,将队列中的消息发送出去
let queueLength = messageQueue.length
for (let i = 0; i < queueLength; i++) {
const messageQueueElement = messageQueue.shift();
wx.sendSocketMessage({
data: messageQueueElement
})
}
})
// 监听 WebSocket 接受到服务器的消息事件
wx.onSocketMessage(function (res) {
ws.onmessage(res);
})
// 监听 WebSocket 错误事件
wx.onSocketError(function (res) {
console.log("WebSocket 错误事件")
})
// 监听 WebSocket 连接关闭事件
wx.onSocketClose(function (res) {
console.log("WebSocket 连接关闭")
socketConnected = false;
// 断线重连
if (reconnect) {
connect();
}
})
后台:
package com.example.websocket.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.scheduling.concurrent.DefaultManagedTaskScheduler;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic", "/user")
.setHeartbeatValue(new long[]{10000L, 10000L})
.setTaskScheduler(new DefaultManagedTaskScheduler());
config.setApplicationDestinationPrefixes("/app");
config.setUserDestinationPrefix("/user");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/send").addInterceptors(new HttpHandshakeInterceptor()).setAllowedOrigins("*");
}
}
后台获取到数据再通过stomp消息转发功能,小程序接收后记得要改一下json格式,再通过页面渲染接收到数据。
公众号接收通知并定时提醒:由于公众号功能不能频繁发送会被平台警告,所以必须记录上一次的发送时间,根据时间来重新判断是否超过警告数值,有警告再重新发送。
流程:
1.调用https://open.weixin.qq.com/connect/oauth2/authorize接口获取到code
2.得到code作为一个参数调用https://api.weixin.qq.com/sns/oauth2/access_token接口获取到openid
(ps.这里只是写死了固定的openid并没有经过网页授权方式,如果要获取所有关注用户openid必须要设置设置网页授权。)
/**
* 测试发送模板消息
*
* @return 当前时间
*/
@RequestMapping("/sendMessage")
public String sendMessage() {
String accessToken = tokenService.getAccessToken();
log.info("获取accessToken=" + accessToken);
Template template = new Template();
template.setTouser("xxxxxxx");
template.setTemplate_id("xxxxxx");
TemplateData first = new TemplateData("请注意,以下设备环境噪音可能超标!", "#173177");
TemplateData keyword1 = new TemplateData("小学部教学楼3楼走廊", "#173177");
TemplateData keyword2 = new TemplateData("12345678", "#173177");
TemplateData keyword3 = new TemplateData("80分贝", "#173177");
TemplateData keyword4 = new TemplateData("2018-11-26 11:43:21", "#173177");
TemplateData keyword5 = new TemplateData("红色", "#FF0000");
TemplateData remark = new TemplateData("请前往设备安装点查看", "#173177");
template.getData().put("first", first);
template.getData().put("keyword1", keyword1);
template.getData().put("keyword2", keyword2);
template.getData().put("keyword3", keyword3);
template.getData().put("keyword4", keyword4);
template.getData().put("keyword5", keyword5);
template.getData().put("remark", remark);
String sendMessageUrl = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + accessToken;
ResponseEntity stringResponseEntity = restTemplate.postForEntity(sendMessageUrl, template, String.class);
System.out.println(stringResponseEntity.getBody());
return LocalDateTime.now().toString();
}
ending:有问题欢迎指出。