开发笔记——websocket

从网上找的,又经过了自己的改良,由于新手,技术残次,写这些也是为了起到笔记的作用,高手勿喷!

 

服务器端:

1.servlet继承WebSocketServlet,重写createWebSocketInbound方法。


 

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.StreamInbound;
import org.apache.catalina.websocket.WebSocketServlet;

import com.websocket.servlet.impl.WebSocketMessageInbound;

@WebServlet(name = "ChatWebSocket", urlPatterns = "/Chat")
public class ChatWebSocket extends WebSocketServlet {
	
	 
	private static final long serialVersionUID = -1058445282919079067L;

	
	@Override
	protected StreamInbound createWebSocketInbound(String arg0, HttpServletRequest request) {
		return new WebSocketMessageInbound(request);
	}
	

}


2.WebSocketMessageInbound继承MessageInbound,重写onOpen(打开连接)、onClose(关闭连接)、onBinaryMessage、onTextMessage(发送消息),带了个request是想从其中获取参数,比如和谁聊天等

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.catalina.websocket.MessageInbound;
import org.apache.catalina.websocket.WsOutbound;
import org.apache.log4j.Logger;

import com.chat.model.ChatDataModel;
import com.chat.service.ChatService;
import com.chat.service.impl.ChatServiceImpl;
import com.websocket.xml.WebSocketToString;

public class WebSocketMessageInbound extends MessageInbound {
	private static Map<Integer, WebSocketMessageInbound> connections = new HashMap<Integer, WebSocketMessageInbound>();
	
	private static Integer count = 0;
	Logger logger = Logger.getLogger(getClass());
	
	private Integer iUserId;
	private Integer iFid;
	
	public WebSocketMessageInbound(HttpServletRequest request){
				
		String sUserId = request.getParameter("uid");
		this.iUserId = Integer.valueOf(sUserId);
		String sFid = request.getParameter("fid");
		this.iFid = Integer.valueOf(sFid);
	}
	
	public Integer getUser(){
		return this.iUserId;
	}
	public	Integer getFid(){
		return this.iFid;
	}
	
	//连接websocket,并获取缓存中的对话
	@Override
	protected void onOpen(WsOutbound outbound) {
		connections.put(iUserId, this);
		logger.info("用户---" + iUserId + "---加入聊天");
		count++;
		logger.info("在线人数:--" + count + "--人");
		
		ChatData chatData= new ChatData();
		Map<Integer, List<ChatDataModel>> chatToMeMap = chatData.getChatNumByUserId(iUserId);
		if(chatToMeMap != null){
			try {
				String strResponse = WebSocketToString.receiveChatToString(chatToMeMap);
				this.getWsOutbound().writeTextMessage(CharBuffer.wrap(strResponse));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onClose(int status) {
		connections.remove(iUserId);
		logger.info("用户---" + iUserId + "---退出聊天");
		count--;
		logger.info("在线人数:--" + count + "--人");
	}

	@Override
	protected void onBinaryMessage(ByteBuffer buffer) throws IOException {
		// TODO Auto-generated method stub

	}

	//发送聊天内容,  如果在线直接通过websocket发送,  不过不在线存到缓存
	@Override
	protected void onTextMessage(CharBuffer message) throws IOException {
		//得到对方connection
		WebSocketMessageInbound inbound = connections.get(iFid);
		ChatDataModel chatDataModel = new ChatDataModel();
		
		chatDataModel.setSend_id(iUserId);
		chatDataModel.setRecieive_id(iFid);
		chatDataModel.setContent(message.toString());
		long time = new Date().getTime();
		chatDataModel.setTime(time);
		
		StringBuffer sInfo = new StringBuffer();
		//如果对方在线
		if(inbound != null){
			logger.info(iFid + "  在线");
		
			inbound.getWsOutbound().writeTextMessage(CharBuffer.wrap(chatDataModel.toString()));
			logger.info(iUserId+"  对      "+iFid+"说:"+chatDataModel.getContent());
			sInfo.append("发送成功");
			
		//如果对方不在线
		}else{
			logger.info(iFid +"  不在线");
			ChatData chatData= new ChatData();
			chatData.setChatById(iUserId, iFid, chatDataModel);
			logger.info(iUserId+"  对      "+iFid+"说:"+chatDataModel.getContent());
			logger.info("已经放入缓存");
			sInfo.append("对方暂时没有收到消息,已经保存到服务器");
		}
		
		this.getWsOutbound().writeTextMessage(CharBuffer.wrap(sInfo.toString()));
	}

}


   其中chatServiceImpl类里面提供的方法是用来保存不在线用户的聊天记录的,当用户上线的时候先获取缓存中的记录。

3.ChatData如下

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import com.chat.model.ChatDataModel;

public class ChatData {

	static Logger logger = Logger.getLogger(ChatData.class);

	static Map<Integer, Map<Integer, List<ChatDataModel>>> mapChat = new Hashtable<Integer, Map<Integer, List<ChatDataModel>>>();
	
	
	public static Map<Integer, List<ChatDataModel>> mapChatToMeNum(Integer iUserId){
		
		return  ChatData.mapChat.get(iUserId);
		
	}

	/**
	 * 接收到的
	 * */
	public static List<ChatDataModel> getChatById(Integer iUserId, Integer iPlayerId) {

		// 这个是所有发给我的
		Map<Integer, List<ChatDataModel>> mapReceive = mapChat.get(iUserId);
		logger.debug(mapReceive);

		if (mapReceive == null) {
			return null;
		} else {
			// listReceive = new ArrayList();
			// 这个是Player发给我的
			List<ChatDataModel> listReceive = mapReceive.get(iPlayerId);

			// 取出点对点聊天信息列表后从内存中删除
			mapReceive.remove(iPlayerId);
			return listReceive;
		}

	}

	/**
	 * 发送的
	 * */
	public static boolean setChatById(Integer iUserId, Integer iPlayerId, ChatDataModel chatDataModel) {

		// 从内存获得对方收到的我发的聊天信息列表
		List<ChatDataModel> listSend = getChatById(iPlayerId, iUserId);

		if (listSend == null) {
			listSend = new ArrayList<ChatDataModel>();
		}
		// 列表中加入聊天信息
		listSend.add(chatDataModel);
		// 这个是指定的Player收到的
		Map<Integer, List<ChatDataModel>> mapSend = mapChat.get(iPlayerId);
		if (mapSend == null) {
			mapSend = new HashMap<Integer, List<ChatDataModel>>();
		}

		mapSend.put(iUserId, listSend);
		// 这个是Player接收的所有的
		mapChat.put(iPlayerId, mapSend);
		logger.debug("<setChatById>" + mapChat);
		return true;

	}
	
	//消息个数
	public static int getChatMapCount(Integer iUserId){
		int count = 0;
		for(Entry<Integer, Map<Integer, List<ChatDataModel>>> entry : mapChat.entrySet()){
			if(entry.getKey() == iUserId.intValue()){
				Map<Integer, List<ChatDataModel>> m = entry.getValue();
				System.out.println(m);
				if(m==null){
					break;
				}
				
				for(Entry<Integer, List<ChatDataModel>> en : m.entrySet()){
					List<ChatDataModel> li = en.getValue();
					count +=li.size();
				}
				
			}
		}
		return count;
	}
}


4.model如下

public class ChatDataModel {

	
	private int chat_id;
	
	private Integer send_id;
	
	private Integer recieive_id;
	
	private String content;
	
	private String time;

	public int getChat_id() {
		return chat_id;
	}

	public void setChat_id(int chat_id) {
		this.chat_id = chat_id;
	}

	public Integer getSend_id() {
		return send_id;
	}

	public void setSend_id(Integer send_id) {
		this.send_id = send_id;
	}

	public Integer getRecieive_id() {
		return recieive_id;
	}

	public void setRecieive_id(Integer recieive_id) {
		this.recieive_id = recieive_id;
	}

	public String getContent() {
		return content;
	}

	public void setContent(String content) {
		this.content = content;
	}

	public String getTime() {
		return time;
	}

	public void setTime(String time) {
		this.time = time;
	}

	
	@Override
	public String toString(){
		StringBuffer sb = new StringBuffer();
		String hr = "#|property|#";
		
		sb.append(getSend_id());
		sb.append(hr);
		sb.append(getTime());
		sb.append(hr);
		sb.append(getContent());
		
		
		return sb.toString();
	}
}


 

客户端:

由于没有登录,所以我把jsp写死了,固定为111对222说话

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8" import="java.lang.*"%>
<%
	String path = request.getContextPath();
	String WsBasePath = "ws://" + request.getServerName() + ":"
			+ request.getServerPort() + path + "/";
%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>websocket聊天室</title>
<style type="text/css">
#chat {
	text-align: left;
	width: 600px;
	height: 500px;
	width: 600px;
}

#up {
	text-align: left;
	width: 100%;
	height: 400px;
	border: 1px solid green;
	OVERFLOW-Y: auto;
}

#down {
	text-align: left;
	height: 100px;
	width: 100%;
}
</style>
</head>
<body>
	<h2 align="center">基于HTML5的聊天室</h2>
	<div align="center" style="width: 100%; height: 700px;">
		<div id="chat">
			<div id="up"></div>
			<div id="down">
				<textarea style="width: 602px; height: 100%;" id="send"></textarea>
			</div>
		</div>
		<br/>
		<input type="button" value="连接" οnclick="chat(this);"> <input
			type="button" value="发送" οnclick="send(this);" disabled="disabled"
			id="send_btn" title="Ctrl+Enter发送">
	</div>
</body>
<script type="text/javascript">
	var socket;
	var receive_text = document.getElementById("up");
	var send_text = document.getElementById("send");
	function addText(msg) {
		receive_text.innerHTML += "<br/>" + msg;
		receive_text.scrollTop = receive_text.scrollHeight;
	}
	var chat = function(obj) {
		obj.disabled = "disabled";
		try{
			socket = new WebSocket('<%=WsBasePath + "Chat?uid=111&fid=222"%>');
			receive_text.innerHTML += "<font color=green>正在连接服务器……</font>";
		}catch(e){
			receive_text.innerHTML += "<font color=red>抱歉,您的浏览器不支持html5,请使用IE10或者最新版本的谷歌、火狐等浏览器!</font>";
		}
		//打开Socket 
		socket.onopen = function(event) {
			falg=false;
			addText("<font color=green>连接成功!</font>");
			document.getElementById("send_btn").disabled = false;
			send_text.focus();
			document.onkeydown = function(event) {
				if (event.keyCode == 13 && event.ctrlKey) {
					send();
				}
			};
		};
		socket.onmessage = function(event) {
			addText(event.data);
		};

		socket.onclose = function(event) {
			addText("<font color=red>连接断开!</font>");
			obj.disabled = "";
		};
	};
	var send = function(obj) {
		if (send_text.value == "") {
			return;
		}
		socket.send(send_text.value);
		send_text.value = "";
		send_text.focus();
	};
</script>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值