在使用java作为后台测试微信小程序时,发现:
1.后台中ServerHttpRequest request中的session是空的,前端通过wx.connectSocket传递的data也没看到。
2.可以从前端网后台传递信息,但是后台往前端发送时会报出如下错误
有没有大神能告知下解决方案呢?
Java后台实现WebSocket时一共尝试了两种方案,一种是java+spring,一种是纯spring的,而且两者都会出现上面的情况,同时
其中:
Exception in thread "Thread-21" java.lang.IllegalStateException: The remote endpoint was in state [STREAM_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1225)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textPartialStart(WsRemoteEndpointImplBase.java:1182)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendPartialString(WsRemoteEndpointImplBase.java:222)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:49)
at org.springframework.web.socket.adapter.standard.StandardWebSocketSession.sendTextMessage(StandardWebSocketSession.java:197)
at org.springframework.web.socket.adapter.AbstractWebSocketSession.sendMessage(AbstractWebSocketSession.java:104)
at cn.zhonya.WXTalkDome.webSocket.MyWebSocketHandler$1.run(MyWebSocketHandler.java:139)
at java.lang.Thread.run(Thread.java:745)
java.lang.IllegalStateException: The remote endpoint was in state [WRITER_WRITING] which is an invalid state for called method
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.checkState(WsRemoteEndpointImplBase.java:1225)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase$StateMachine.textStart(WsRemoteEndpointImplBase.java:1187)
at org.apache.tomcat.websocket.WsRemoteEndpointImplBase.sendString(WsRemoteEndpointImplBase.java:190)
at org.apache.tomcat.websocket.WsRemoteEndpointBasic.sendText(WsRemoteEndpointBasic.java:37)
at cn.zhonya.WXTalkDome.webSocket.MyWebSocket.sendMessage(MyWebSocket.java:107)
at cn.zhonya.WXTalkDome.webSocket.MyWebSocket.onMessage(MyWebSocket.java:80)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:399)
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:106)
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:500)
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:295)
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:131)
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:69)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1419)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:44)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
@ServerEndpoint(value = "/websocket2.do",configurator = SpringConfigurator.class)
public class MyWebSocket {
private static int onlineCount = 0;
public MyWebSocket(){
}
@Autowired
private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new CopyOnWriteArraySet<MyWebSocket>();
private static Logger logger = Logger.getLogger(MyWebSocket.class);
private Session session;
/**
* 链接建立成功调用的方法
* @param session 可选的参数,session为与某个客户端连接的会话,需要通过它来给客户发送数据
*/
@OnOpen
public void onOpen(Session session, @PathParam("user") String user,@PathParam("uid") String uid){
this.session = session;
// session.getAttributes();
logger.info("——————————————");
logger.info("——————————————");
logger.info("——————————————");
logger.info("——————————————");
JSONObject s = new JSONObject(session);
String str= session.getQueryString();
String [] strs = str.split("&");
int slen = strs.length;
for(String quey:strs){
String [] q = quey.split("=");
System.out.println("sing:"+q[0]+" value:"+q[1]);
}
logger.info("webSocketSet————————:"+s.toString());
logger.info("——————————————");
logger.info("——————————————");
logger.info("——————————————");
webSocketSet.add(this);//加入set中
addOnlineCount();//在线人数加1
System.out.println("有新链接加入!当前在线人数为:"+getOnlineCount()+" user:"+user+" uid:"+uid);
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose(){
webSocketSet.remove(this);//从set中删除
subOnlineCount();
System.out.println("有一个连接关闭!当前在线人数为:"+getOnlineCount());
}
@OnMessage
public void onMessage(String message,Session session){
System.out.println("来自客户端的消息:"+message);
//群发消息
for(MyWebSocket item:webSocketSet){
try{
if(item.session == session){
// item.sendMessage("<p><span style='color:#ff0000;'>我说:"+message+"</span> <span style='color:#bbbaba;'>当前在线人数:"+getOnlineCount()+"</span></p>");
item.sendMessage(message);
}else{
item.sendMessage("<p>"+message+" 当前在线人数:"+getOnlineCount()+"</p>");
}
}catch (IOException e){
e.printStackTrace();
continue;
}
}
}
@OnError
public void onError(Session session,Throwable error){
System.out.println("发生错误");
error.printStackTrace();
}
/**
* 这个方法与上面几个方法不一样,没有用注解,根据自己需要添加的方法
* @param message
*/
private void sendMessage(String message) throws IOException {
//保存到数据库
// Content content = new Content();
// content.setContent(message);
// content.setCreateDate(StringUtilZ.getTimestampOfNow("yyyy-MM-dd HH:mm:ss"));
this.session.getBasicRemote().sendText(message);
}
public static synchronized int getOnlineCount(){
return onlineCount;
}
public static synchronized void addOnlineCount() {
MyWebSocket.onlineCount++;
}
private static synchronized void subOnlineCount(){
MyWebSocket.onlineCount--;
}
}
springmvc自身的那个文件比较多就不多贴了,暂时贴下那个139行上下的内容
public void broadcast(final TextMessage message)throws IOException {
Iterator<Map.Entry<String,WebSocketSession>> it = userSocketSessionMap
.entrySet().iterator();
//多线程群发
while(it.hasNext()){
final Map.Entry<String,WebSocketSession> entry = it.next();
if(entry.getValue().isOpen()){
new Thread(new Runnable() {
public void run() {
try{
if(entry.getValue().isOpen()){
entry.getValue().sendMessage(message);
}
} catch (IOException e){
e.printStackTrace();
}
}
}).start();
}
}
}
这两种方法在普通WebSocket中都没问题,换到微信小程序就只能接受客户端消息,没办法将消息从服务器传到客户端。怀疑是不是那个session的问题啊,在小程序中使用获取到的session就是空的了。
看异常好像是线程状态的问题 异常信息倒数第二行 提示代码有问题 试下 spring boot 才叫简单啊