天天看点

java webscoket聊天室

java webscoket聊天室

http://www.whohelpme.com/chats/index.html

欢迎使用

核心代码

package com.summer.whm.web.controller.chats;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.lang.StringEscapeUtils;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.summer.whm.entiry.chats.ChatsFriendMessage;
import com.summer.whm.entiry.chats.ChatsKeys;
import com.summer.whm.service.chats.ChatsFriendMessageService;
import com.summer.whm.service.chats.ChatsFriendService;
import com.summer.whm.service.chats.ChatsKeysService;
import com.summer.whm.web.common.SpringContainer;
import com.summer.whm.web.common.utils.Base64ForJavascript;
import com.summer.whm.web.controller.chats.model.ChatsContext;
import com.summer.whm.web.controller.chats.model.MessageModel;

@ServerEndpoint(value = "/charts/friend/{key}")
public class ChatsFriendSocket {

    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount = 0;

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

    // 与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    
    private ChatsKeysService chatsKeysService; 
    
    private ChatsFriendMessageService chatsFriendMessageService;
    
    private ChatsFriendService chatsFriendService;
    
    public static final String MESSAGE_KEY_TYPE = "type";
    
    public static final String MESSAGE_KEY_CONTENT = "content";
    
    /**
     * 连接建立成功调用的方法
     * 
     * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("key") String key, Session session) {
        this.session = session;
        
        ChatsContext chatsContext = new ChatsContext();
        chatsContext.setChatkey(key);
        chatsContext.setFriendSocket(this);
        
        ChatsKeys chatsKeys = checkChatkey(key);
        chatsContext.setNickname(null);
        chatsContext.setUsername(chatsKeys.getObjId());

        webSocketMap.put(key, chatsContext);
        addOnlineCount(); // 在线数加1
        System.out.println(key + "加入!当前在线人数为" + getOnlineCount());
    }

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

    /**
     * 收到客户端消息后调用的方法
     * 
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     * @throws IOException 
     */
    @OnMessage
    public void onMessage(@PathParam("key") String key, String message, Session session) throws IOException {
        System.out.println("来自客户端的消息:" + message);

        MessageModel messageModel = null;
        Map<String, String> messageMap = new HashMap<String, String>();
        String messageJson = null;
        try{
           messageModel = JSON.parseObject(message, MessageModel.class);
           String tempContent = Base64ForJavascript.decode(messageModel.getContent());
           messageModel.setContent(tempContent);
           
           boolean isOnLine = false;
           ChatsContext chatsContext = webSocketMap.get(messageModel.getChatkey());
           //如果不null,测接受人不在线,
           
           if(chatsContext != null){
               //发送给接受人消息
               messageMap.put(MESSAGE_KEY_TYPE, "1");//接受消息
               messageMap.put(MESSAGE_KEY_CONTENT, messageModel.getContent());
               messageMap.put("userChatkey", messageModel.getUserChatkey());
               messageMap.put("username", messageModel.getUsername());
               messageJson = JSON.toJSONString(messageMap);
               chatsContext.getFriendSocket().sendMessage(messageJson);
               isOnLine = true;
           }
           
           ChatsFriendMessage chatsFriendMessage = createChatsFriendMessage(messageModel ,isOnLine);
           this.chatsFriendMessageService.saveOrUpdate(chatsFriendMessage);
           
           //发送消息给自己,如果走到这一步,基本上可以确定消息已经成功发出
           chatsContext = webSocketMap.get(messageModel.getUserChatkey());
           
           messageMap.put(MESSAGE_KEY_TYPE, "0");//发送消息
           messageMap.put(MESSAGE_KEY_CONTENT, escapeContent(messageModel.getContent()));
  
           messageJson = JSON.toJSONString(messageMap);
           chatsContext.getFriendSocket().sendMessage(messageJson);
       }catch(Exception e){
           if(messageModel != null){
               messageMap.put(MESSAGE_KEY_TYPE, "99");//错误
               messageMap.put(MESSAGE_KEY_CONTENT,  "消息格式错误。");
               ChatsContext chatsContext = webSocketMap.get(messageModel.getUserChatkey());
               messageJson = JSON.toJSONString(messageMap);
               chatsContext.getFriendSocket().sendMessage(messageJson);
           }
           e.printStackTrace();
       }
    }

    public String escapeContent(String content){
        if(content != null){
           return StringEscapeUtils.escapeHtml(content);
        }
        
        return "";
    }
    
    public List<Map<String, String>> buildMessage(Map<String, String> messageMap){
        List<Map<String, String>> list = new ArrayList<Map<String, String>>();
        Map<String, String> map = null;
        if(messageMap != null && messageMap.get(MESSAGE_KEY_CONTENT) != null){
            if(messageMap.get(MESSAGE_KEY_CONTENT).length() > 1000){
                String content = messageMap.get(MESSAGE_KEY_CONTENT);
                String temp = "";
                int length = content.length();
                int max = length / 1000;
                if(max * 1000 < length){
                    max++;
                }
                int begin = 0;
                int end = 0;
                for(int i = 0; i < max; i++){
                    begin = i * 1000;
                    end = begin + 1000;
                    if(end > length){
                        end = length;
                    }
                    temp = content.substring(begin, end);
                    map = new HashMap<String, String>();
                    map.putAll(messageMap);
                    map.put(MESSAGE_KEY_CONTENT, temp);
                    
                    list.add(map);
                }
            }else{
                list.add(messageMap);
            }
        }
        
        return list;
        
    }
    
    /**
     * 发生错误时调用
     * 
     * @param session
     * @param error
     */
    @OnError
    public void onError(@PathParam("key") String key, Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }

    public ChatsKeys checkChatkey(String key){
        ChatsKeys chatsKeys = getChatsKeysService().queryByChatkey(key);
        return chatsKeys;
    }
    
    public ChatsFriendMessage createChatsFriendMessage(MessageModel messageModel, boolean isRead){
        ChatsFriendMessage chatsFriendMessage = new ChatsFriendMessage();
        ChatsContext chatsContext = null;
        
        if(isRead){
            chatsContext = webSocketMap.get(messageModel.getChatkey());
            chatsFriendMessage.setAcceptname(chatsContext.getUsername());
            chatsFriendMessage.setStatus("1");
        }else{
            ChatsKeys chatsKeys = this.getChatsKeysService().queryByChatkey(messageModel.getChatkey());
            chatsFriendMessage.setAcceptname(chatsKeys.getObjId());
            chatsFriendMessage.setStatus("0");
        }
        
        chatsFriendMessage.setContent(messageModel.getContent());
        chatsFriendMessage.setUsername(messageModel.getUsername());
        
        String messageId =  this.getChatsFriendMessageService().getMessageId(chatsFriendMessage.getUsername(), chatsFriendMessage.getAcceptname());
        chatsFriendMessage.setMessageId(messageId);
        
        chatsFriendMessage.setCreator(messageModel.getUsername());
        chatsFriendMessage.setCreateTime(new Date());
        chatsFriendMessage.setLastUpdate(new Date());
        return chatsFriendMessage;
    }
    
    /**
     * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
     * 
     * @param message
     * @throws IOException
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

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

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

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

    public ChatsKeysService getChatsKeysService() {
        
        if(chatsKeysService == null){
            chatsKeysService = SpringContainer.getBean(ChatsKeysService.class);
        }
        
        return chatsKeysService;
    }

    public ChatsFriendMessageService getChatsFriendMessageService() {
        
        if(chatsFriendMessageService == null){
            chatsFriendMessageService = SpringContainer.getBean(ChatsFriendMessageService.class);
        }
        
        return chatsFriendMessageService;
    }

    public ChatsFriendService getChatsFriendService() {
        if(chatsFriendService == null){
            chatsFriendService = SpringContainer.getBean(ChatsFriendService.class);
        }
        
        return chatsFriendService;
    }
}