@RequestMapping ( "login" )
public ReturnValue login(HttpServletRequest request, HttpServletResponse response) throws Exception {
String userId = request.getParameter( "userId" );
String proxyId=request.getParameter( "proxyId" );
String workOrderId=request.getParameter( "workOrderId" );
String clientType=request.getParameter( "clientType" );
if (Strings.isBlank(userId)||Strings.isBlank(proxyId)||Strings.isBlank(workOrderId)||Strings.isBlank(clientType)) {
return new ReturnValue( false , "参数异常" );
}
HttpSession session = request.getSession();
if ( null !=session) {
System.out.println( "登陆WebSocket成功:" +( "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId));
session.setAttribute( "WEBSOCKET_SESSSION_ID" , "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId);
} else {
System.out.println( "登陆WebSocket失败,session==null:" +( "1" .equals(clientType)? "P" +proxyId+workOrderId: "U" +userId+workOrderId));
logger.error( "登录websocket+login时,获取session失败" );
}
return new ReturnValue( true );
}
|
这是小程序登录websocket 时的代码,当在session 中设置好键值后,在spring tcp握手连接时得不到这个session 和其中的值。
下面是tcp 握手连接时的代码 ,就是得不到session ,但是浏览器端是可以的,因为他加了xhrFields 带了凭证可以保证得到的session是一致的,
var url="<%=afterSaleServer%>/ptt/controller/websocket/websocketcontroller/login";
$.ajax({
url: url,
type: 'post',
async:false,
data: messageJsonLogin,
xhrFields: {
withCredentials: true//允许带上凭据
},
crossDomain: true,
success:function(res){
if(res.code=="200"){
if ('WebSocket' in window) {
ws = new WebSocket(""+socketUrl+"/ptt/websocket/socketServer");
console.log("连接成功");
}
else if ('MozWebSocket' in window) {
ws = new MozWebSocket(""+socketUrl+"/ptt/websocket/socketServer");
}
else {// 这个是应对浏览器不支持websocket协议的时候降级为轮询的处理。
ws = new SockJS("https://"+socketUrl+"/ptt/sockjs/socketServer");
}
}
},
error:function(){
}
});
|
@Override
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
Map<String, Object> attributes) throws Exception {
System.out.println( "Before Handshake" );
if (request instanceof ServletServerHttpRequest) {
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
HttpSession session = servletRequest.getServletRequest().getSession();
System.out.println( "握手时,获取到的session:" +session);
if (session != null ) {
String sessionId = (String) session.getAttribute( "WEBSOCKET_SESSSION_ID" );
if (sessionId!= null ) {
attributes.put( "WEBSOCKET_SESSSION_ID" ,sessionId);
}
String sessionNo_workOrderId = (String) session.getAttribute( "WEBSOCKET_NO_WORKORDER_WAIT_MESSAGE_SESSSION_ID" );
if (sessionNo_workOrderId!= null ) {
attributes.put( "WEBSOCKET_NO_WORKORDER_WAIT_MESSAGE_SESSSION_ID" ,sessionNo_workOrderId);
}
}
}
return super .beforeHandshake(request, response, wsHandler, attributes);
}
|
下面是小程序端的代码,虽然我每次请求都发送了sessionId, 但是都是没有用,就是获取不到session,为什么要获取这个session呢?
loginWebSocket({ workOrderId: workOrderId, userId: userId, proxyId: proxyId, clientType: clientType}).then(
console.log("登陆成功"),
wx.connectSocket({
url: "" + socketUrl + "/ptt/websocket/socketServer",
success() {
console.log('连接成功')
that.initEventHandle()
}
})
);
|
initEventHandle() {
let that = this
wx.onSocketMessage((res) => {
console.log("收到消息",res);
//收到消息
if (res.data == "pong") {
heartCheck.reset().start()
} else {
//处理数据
console.log(res.data);
var nowDate2 = util.formatDate(new Date());//发送日期
var nowTime2 = util.formatNowTime(new Date());//发送时间
var messageJson2 = {};
messageJson2.content = res.data;
messageJson2.makeDate = nowDate2;
messageJson2.makeTime = nowTime2;
messageJson2.proxyId = proxyId;
messageJson2.userId = null;
var array2 = that.data.leaveMsgList;
array2.push(messageJson2);
that.setData({
leaveMsgList: array2
});
that.toButtom();
}
})
wx.onSocketOpen(() => {
console.log('WebSocket连接打开')
heartCheck.reset().start()
})
wx.onSocketError((res) => {
console.log('WebSocket连接打开失败')
this.reconnect()
})
wx.onSocketClose((res) => {
console.log('WebSocket 已关闭!')
this.reconnect()
})
},
reconnect:function() {
console.log(this.lockReconnect);
if (this.lockReconnect) return;
this.lockReconnect = true;
console.log("....");
clearTimeout(this.timer)
if (this.data.limit < 12 ) {
this.timer = setTimeout (() => {
this.linkWebSocket();
this.lockReconnect = false;
}, 5000);
this.setData({
limit: this.data.limit + 1
})
}
},
|
因为要通过在session 中设置的值来往 集合中放入session,方便对这个session 发送消息
/**
* 连接成功时候,会触发页面上onopen方法
*/
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
System.out.println( "成功建立websocket连接!" );
String userId = (String) session.getAttributes().get(USER_ID);
String no_workOrderId_userId = (String) session.getAttributes().get(No_WORKORDER_USERID);
System.out.println( "成功建立websocket连接 userId=!" +userId);
System.out.println( "成功建立websocket连接no_workOrderId_userId=!" +no_workOrderId_userId);
if (Strings.isNotBlank(userId)) {
if (users.containsKey(userId)) {
WebSocketSession wss=users.get(userId);
wss.close();
}
users.put(userId,session);
}
if (Strings.isNotBlank(no_workOrderId_userId)) {
if (users.containsKey(no_workOrderId_userId)) {
WebSocketSession wss=users.get(no_workOrderId_userId);
wss.close();
}
users.put(no_workOrderId_userId,session);
}
System.out.println( "当前线上用户数量:" +users.size());
users.entrySet().forEach(System.out::println);
System.out.println( ".......以上为用户session数量" );
}
|
/**
* 给某个用户发送消息
*
* @param userId
* @param message
*/
public void sendMessageToUser(String userId, TextMessage message) {
logger.error( "开始发送消息!给->" +userId + " 信息" +message);
for (String id : users.keySet()) {
logger.error( "目前有:键值" +id+ " 会话" +users.get(id));
if (id.equals(userId)) {
try {
if (users.get(id).isOpen()) {
users.get(id).sendMessage(message);
logger.error( "成功发送消息给:" +userId);
}
} catch (IOException e) {
e.printStackTrace();
}
break ;
}
}
}
|
跪求大佬们,耽误好几天了,在开发工具当中没有问题,但是小程序到了真机和体验版时,一致有这个问题