websocket实例问题

前提:用websocket做一个网页版的聊天室,要求能显示在线用户,我在数据库中创建了loginstatu字段,当用户登陆时修改字段标识已经登陆并且把sessionid写入到数据库的sessionid字段中,当用户关闭浏览器等操作,也就是与websocket断开连接时通过表中sessionid字段找到用户,把loginstatu修改为未登陆状态。
问题:在websocket中使用`session.getOpenSessions()`来获取所有的连接时,他只是会返回当前发送消息的session,通过测试发现可能是每一个连接都去创建了一个websocket实例,所以session集合中只有一个session。
相关代码如下:
websocket.java
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.zfx.entity.User;
import com.zfx.service.UserService;
import net.sf.json.JSONObject;
/**
 * Created by onedayrex on 2016/1/10.
 */
@ServerEndpoint("/websocket")
public class WebSocket {
    private static final UserService userService = new UserService();
    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 日期格式化
    @OnOpen
    public void open(Session session) {
        // 添加初始化操作
        System.out.println("已经连接到客户" + session.getId());
    }
    /**
     * 接受客户端的消息,并把消息发送给所有连接的会话
     * @param message 客户端发来的消息
     * @param session 客户端的会话
     */
    @OnMessage
    public void getMessage(String message, Session session) {
        // 把客户端的消息解析为JSON对象
        JSONObject jsonObject = JSONObject.fromObject(message);
        // 在消息中添加发送日期
        int statu = jsonObject.getInt("statu");
        if (statu==1) {
            jsonObject.put("date", DATE_FORMAT.format(new Date()));
            jsonObject.put("putstatu",0);
            // 把消息发送给所有连接的会话
            for (Session openSession : session.getOpenSessions()) {//遍历用户
                // 检测是否为本次会话所发送的标志,并添加到JSON对象里
                jsonObject.put("isSelf", openSession.equals(session));
                // 发送JSON格式的消息
                openSession.getAsyncRemote().sendText(jsonObject.toString());
            }
            System.out.println(message);
        } else if(statu==0){
            //当用户登陆后向所有用户通知该用户已经登陆的消息
            userService.bindsessionid(session.getId(),jsonObject.getString("username"));
            userService.userLogin(jsonObject.getString("username"));
            JSONObject userlog = new JSONObject();
            userlog.put("putstatu",1);
            userlog.put("username",jsonObject.getString("username"));
            for(Session open:session.getOpenSessions()){
                open.getAsyncRemote().sendText(userlog.toString());
            }
        }

    }
    @OnClose
    public void close(Session session) {
        // 添加关闭会话时的操作
        String sessionid = session.getId();
        userService.userlogout(sessionid);
        System.out.println("断开连接"+session.getId());

    }
    @OnError
    public void error(Throwable t) {
        // 添加处理错误的操作
        System.out.println("出错,错误信息"+t);
    }
}
阅读 6.9k
2 个回答

package com.hq.chat;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

/**

  • 聊天服务器类

  • @author wwx
    *必须tomcat8及以上

*
*/
@ServerEndpoint("/websocket")
public class ChatServer {
// private static final Log log = LogFactory.getLog(ChatAnnotation.class);

  
private static final String GUEST_PREFIX = "Guest";  
private static final AtomicInteger connectionIds = new AtomicInteger(0); 
private static final Set<ChatServer> connections = new CopyOnWriteArraySet<>();  

private final String nickname;  
private Session session;  

public ChatServer() {  
    nickname = GUEST_PREFIX + connectionIds.getAndIncrement();  //线程安全并自增
}  
  
//建立连接  
@OnOpen  
public void start(Session session) {  
    this.session = session;  
    connections.add(this);  
    String message = String.format("* %s %s", nickname, "has joined.");  
    System.out.println(message);  
    //广播客户端加入
    broadcast(message.toString());  
}  
  
//接受消息  
@OnMessage  
public void incoming(String message) {  
    System.out.println(message.toString());  
    //广播消息
    broadcast(message.toString());  
}  
  
//客户端关闭了连接  
@OnClose  
public void end() {  
    connections.remove(this);  
    String message = String.format("* %s %s", nickname, "has disconnected.");  
    System.out.println(message);  
    //广播客户端退出
    //broadcast(message);  
}  
  
//WebSocket服务出错  
@OnError  
public void onError(Throwable t) throws Throwable {  
    //log.error("Chat Error: " + t.toString(), t);  
}  

 /**
  * 广播
  */
private static void broadcast(String msg) {  
    for (ChatServer client : connections) {  
        try {  
            synchronized (client) {  
                client.session.getBasicRemote().sendText(msg);  
            }  
        } catch (IOException e) {  
            //log.debug("Chat Error: Failed to send message to client", e);  
            connections.remove(client);  //移除问题连接
            try {  
                client.session.close();  
            } catch (IOException e1) {  
                // Ignore  
            }  
            String message = String.format("* %s %s",  
                    client.nickname, "has been disconnected.");  
            broadcast(message);  
        }  
    }  
}  

}

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题