websocket问题,服务器往客户端发送数据会崩溃

连接成功且客户端发送过来的数据能在服务器显示,可是执行this.session.getBasicRemote().sendText(message);会崩溃

3个回答

不清楚你的错误信息是什么,我也实现了一个,没有错误。

以下是代码

 package websocket;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

@ServerEndpoint("/websocket/{name}")
public class WebSockate {
    // 当前在线人数
    private static int inlineCount = 0;
    // 连接集合
    private static CopyOnWriteArraySet<WebSockate> webSocketSet = new CopyOnWriteArraySet<WebSockate>();
    // session
    Session session = null;

    @OnOpen
    public void onOpen(Session session) {
        this.session = session;
        // 线程不安全
        inlineCount++;
        System.out.println("多了一个=>" + inlineCount);
        webSocketSet.add(this);
    }

    @OnMessage
    public void onMessage(String message,@PathParam("name")String name) {
        //System.out.println(name);
        for (WebSockate socket : webSocketSet) {
            String str = "var message=[]; message[\"name\"]='"+name+"';message[\"message\"]='"+message+"'";
            socket.sendMessage(str);
        }
    }

    @OnClose
    public void onClose() {
        webSocketSet.remove(this);
        inlineCount--;
        System.out.println("少了一个->" + inlineCount);
    }

    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    //发送消息
    public void sendMessage(String message) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

sacred9
holyenvoy 我的跟你代码几乎一样。。代码放在3楼,麻烦看下!
3 年多之前 回复

package com;

import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;

/**

  • @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
  • 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
    */
    @ServerEndpoint("/websocket")
    public class MyWebSocket {
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static CopyOnWriteArraySet webSocketSet = new CopyOnWriteArraySet();

    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;

    /**

    • 连接建立成功调用的方法
    • @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据 */ @OnOpen public void onOpen(Session session){ this.session = session; webSocketSet.add(this); //加入set中 addOnlineCount(); //在线数加1 System.out.println("有新连接加入!当前在线人数为" + getOnlineCount()); System.out.println("sesion ID:" + session); }

    /**

    • 连接关闭调用的方法 */ @OnClose public void onClose(){ webSocketSet.remove(this); //从set中删除 subOnlineCount(); //在线数减1 System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount()); }

    /**

    • 收到客户端消息后调用的方法
    • @param message 客户端发送过来的消息
    • @param session 可选的参数
      */
      @OnMessage
      public void onMessage(String message) throws IOException, InterruptedException{
      System.out.println("来自客户端的消息:" + message);
      for(MyWebSocket item: webSocketSet){
      try {
      if (this.session!=item.session) {
      item.sendMessage(message);
      }

      } catch (IOException e) {
          e.printStackTrace();
          continue;
      }
      

      }
      }

    /**

    • 发生错误时调用
    • @param session
    • @param error */ @OnError public void onError(Session session, Throwable error){ System.out.println("发生错误"); error.printStackTrace(); }

    /**

    • 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
    • @param message
    • @throws IOException */ public void sendMessage(String message) throws IOException{ session.getBasicRemote().sendText(message); }

    public static synchronized int getOnlineCount() {
    return onlineCount;
    }

    public static synchronized void addOnlineCount() {
    MyWebSocket.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
    MyWebSocket.onlineCount--;
    }
    }

kingGCL
游gcl 你把你的项目发给我,我看看
3 年多之前 回复
sacred9
holyenvoy 回复幻想家gcl: 你用的是myEclipse?我用的是eclipse,要不要手动导入什么包的?
3 年多之前 回复
kingGCL
游gcl 回复holyenvoy: 关于底层的实现我也不清楚,在我电脑上测试的没有问题。*_*
3 年多之前 回复
sacred9
holyenvoy 回复幻想家gcl: 有新连接加入!当前在线人数为1 sesion ID:org.apache.tomcat.websocket.WsSession@6e15582a 有新连接加入!当前在线人数为2 sesion ID:org.apache.tomcat.websocket.WsSession@7072ac3d 来自客户端的消息:sss 发生错误 java.io.IOException: 远程主机强迫关闭了一个现有的连接。 at sun.nio.ch.SocketDispatcher.write0(Native Method) at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51) at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93) at sun.nio.ch.IOUtil.write(IOUtil.java:65)
3 年多之前 回复
sacred9
holyenvoy 回复幻想家gcl: 浏览器A发送信息,浏览器B会断开连接,浏览器A正常
3 年多之前 回复
kingGCL
游gcl 我试了一下,你的代码没错。一个问题就是收不到自己发的消息,你打开两个浏览器同时连接试试就知道了
3 年多之前 回复

我也遇到同你一样的问题解决方案:
把item.sendMessage(message);
改为item.sendMessage(item.session, message); _
把public void sendMessage(String message) throws IOException{ session.getBasicRemote().sendText(message); }
_改为public void sendMessage(MyWebSocket mySocket, String message) throws IOException{ mySocket.getBasicRemote().sendText(message); }

就好了

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!