服务器是WindowsServer2012用了nginx的反向代理
服务端是java微信访问websocket wss https协议
小程序的简单连接代码
wx.connectSocket({
url: 'wss://www.*****.com',
})
wx.onSocketMessage(function (res) {
var data = JSON.parse(res.data);
console.log(data);
});
java代码
package com.sourcecontrol.webSocket;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.websocket.EncodeException;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.google.gson.Gson;
import com.sourcecontrol.bean.Msg;
import com.sourcecontrol.service.impl.PlcDataServiceImpl;
@ServerEndpoint("/getdata")
public class GetDataWebSocket {
private Session session;
private static Set<GetDataWebSocket> sockets = new HashSet<GetDataWebSocket>();
private Gson gson = new Gson();
//因为websocket不在spring的注解中所以这里不能使用注解的方式注入service层
ClassPathXmlApplicationContext cc =
new ClassPathXmlApplicationContext(new String[] {"config/applicationContext.xml"});
private PlcDataServiceImpl plcDataServiceImpl = (PlcDataServiceImpl) cc.getBean("plcDataServiceImpl");
// 这个也可以替代上面的的bean注入 但是测试后发现多个浏览器访问后创建的内存地址是一致
// private PlcDataServiceImpl plcDataServiceImpl = (PlcDataServiceImpl) ContextLoader.getCurrentWebApplicationContext().getBean("plcDataServiceImpl");
@OnOpen
public void open(Session session) throws EncodeException {
this.session = session;
sockets.add(this);
String queryString = session.getQueryString();
String deviceId = queryString.split("=")[1];
doTime(deviceId);
}
@OnError
public void error(Throwable t) {
System.out.println(t.toString());
}
@OnClose
public void close(Session session) {
sockets.remove(this);
}
//获取数据库的数据
public Msg getPLCData(String deviceId) {
System.out.println("plcDataService:"+plcDataServiceImpl);
List<Map<String,Object>> plcData = plcDataServiceImpl.getDataByDeviceId(deviceId);
return new Msg(plcData);
}
//定时向微信小程序端发送数据
public void doTime(String deviceId) {
final String dev = deviceId;
Runnable runnable = new Runnable() {
public void run() {
try {
sendText(dev);
} catch (EncodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 0, 10, TimeUnit.MINUTES);
}
//发送数据
public void sendText(String deviceId) throws EncodeException {
//GetDataWebSocket socket = new GetDataWebSocket();
try {
Msg msg= getPLCData(deviceId);
this.session.getBasicRemote().sendText(gson.toJson(msg));
}catch (IOException e) {
e.printStackTrace();
}
}
}
import com.google.gson.Gson;
import com.sourcecontrol.bean.Msg;
import com.sourcecontrol.service.impl.PlcDataServiceImpl;
@ServerEndpoint("/getdata")
public class GetDataWebSocket {
private Session session;
private static Set<GetDataWebSocket> sockets = new HashSet<GetDataWebSocket>();
private Gson gson = new Gson();
//因为websocket不在spring的注解中所以这里不能使用注解的方式注入service层
ClassPathXmlApplicationContext cc =
new ClassPathXmlApplicationContext(new String[] {"config/applicationContext.xml"});
private PlcDataServiceImpl plcDataServiceImpl = (PlcDataServiceImpl) cc.getBean("plcDataServiceImpl");
// 这个也可以替代上面的的bean注入 但是测试后发现多个浏览器访问后创建的内存地址是一致
// private PlcDataServiceImpl plcDataServiceImpl = (PlcDataServiceImpl) ContextLoader.getCurrentWebApplicationContext().getBean("plcDataServiceImpl");
@OnOpen
public void open(Session session) throws EncodeException {
this.session = session;
sockets.add(this);
String queryString = session.getQueryString();
String deviceId = queryString.split("=")[1];
doTime(deviceId);
}
@OnError
public void error(Throwable t) {
System.out.println(t.toString());
}
@OnClose
public void close(Session session) {
sockets.remove(this);
}
//获取数据库的数据
public Msg getPLCData(String deviceId) {
System.out.println("plcDataService:"+plcDataServiceImpl);
List<Map<String,Object>> plcData = plcDataServiceImpl.getDataByDeviceId(deviceId);
return new Msg(plcData);
}
//定时向微信小程序端发送数据
public void doTime(String deviceId) {
final String dev = deviceId;
Runnable runnable = new Runnable() {
public void run() {
try {
sendText(dev);
} catch (EncodeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
ScheduledExecutorService service = Executors
.newSingleThreadScheduledExecutor();
// 第二个参数为首次执行的延时时间,第三个参数为定时执行的间隔时间
service.scheduleAtFixedRate(runnable, 0, 10, TimeUnit.MINUTES);
}
//发送数据
public void sendText(String deviceId) throws EncodeException {
//GetDataWebSocket socket = new GetDataWebSocket();
try {
Msg msg= getPLCData(deviceId);
this.session.getBasicRemote().sendText(gson.toJson(msg));
}catch (IOException e) {
e.printStackTrace();
}
}
}
nginx的配置
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
sendfile on;
keepalive_timeout 65;
server {
listen 443 ssl;
server_name www.*.com.cn; #域名
ssl_certificate www.****.crt; #ssl的证书
ssl_certificate_key www.*****.key; #ssl的秘钥 证书和秘钥我放在和conf文件夹下和nginx.conf同一级别
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;
#默认时间是60s超过60s后websocket将不会推送数据 我的是10分钟推送一次
proxy_read_timeout 3600s;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
#root html;
#index index.html index.htm;
}
}
}
运行结果
第一次发表不喜勿喷,欢迎讨论