websocket技術,實現單聊和群聊

YaYicho發表於2016-08-26

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">基於我上次寫的有關tomcat自帶的websocket的簡單搭建,搭建的連結:http://blog.csdn.net/yayicho/article/details/52080486</span>

搭建步驟我就不多說了下面是我寫的單聊和群聊的案例

前臺的程式碼

1、登陸頁面,是為了實現多使用者線上聊天,說白了就是為了測試

這步就省略了

在後臺登陸後到echo.jsp的傳值

loginServlet.java的關鍵程式碼

String username = request.getParameter("username");
		System.out.println(username);
		request.getSession().setAttribute("textusername", username);
		response.sendRedirect(request.getContextPath()+"/echo.jsp");

echo.jsp程式碼
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'echo.jsp' starting page</title>

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->

<script type="text/javascript" src="js/jquery-1.4.2.js"></script>

<script type="text/javascript">
	var ws = null;
	var content="";
	var target = "ws://localhost:8080/WebSocket/echoSocket?username=${textusername}"
	function connect() {
	//websocket服務連結
		if ('WebSocket' in window) {
			ws = new WebSocket(target);
		} else if ('MozWebSocket' in window) {
			ws = new MozWebSocket(target);
		} else {
			alert('WebSocket is not supported by this browser.');
			return;
		}
		
		//此方法是用來接收後臺傳來的資料,前臺頁面和後臺的資料都是json格式進行傳值
		ws.onmessage = function(event) {
			console.info(event.data);
			eval("var result=" + event.data);
			console.info(result.usernames);
			if (result.usernames != undefined) {
				var html = "";
				$(result.usernames).each(function() {
				 html += "<li><input type='radio' value='"+this+"'name='username'>"+this+"</li>"; 
					$("#userList").html(html);
				});
			}
			
			if (result.welcome != undefined) {
				$("#content").append(result.welcome+"</br>");
			}
			
			if (result.exit != undefined) {
				$("#content").append(result.exit+"</br>");
			}
			if (result.content != undefined) {
				$("#content").append(result.content+"</br>");
			}
			
		};
	}
	function send() {
		var msg = $("#sendMsg").val();
		var ss = $("#userList :checked");
		console.info(ss.val());
		var obj=null;
		//單聊
		if(ss.val()!=undefined){
			obj = {
			//type是用來區分是單聊和群聊
				type:1,//1為單聊,2為群聊
				toUser:ss.val(),
				fromUser:"${textusername}",
				msg:msg
			};
		}else{
			//群聊
			obj = {
				type:2,//1為單聊,2為群聊
				msg:msg
			};
		}
		obj = JSON.stringify(obj);
		console.info(obj);
		ws.send(obj); 
		$("#sendMsg").val("");
	}
</script>
</head>

<body onload="connect();">
	<div id="msg" style="width: 400px;height: 450px; border: solid 1px;">
		<p id="content">
		</p>
	</div>
	<div id="users"
		style="width: 150px;height: 530px;border: solid 1px; position:absolute;left: 412px;top:8px;">
		<p>
		<ul id="userList">
		</ul>
		</p>
	</div>
	<div id="send" style="width: 400px;height:80px;border: solid 1px;"
		align="right">
		<textarea style="width: 400px;height: 50px;" id="sendMsg"></textarea>
		<input type="button" value="傳送訊息" onclick="send();">
	</div>
</body>
</html>

websocket配置(這一步很重要)SocketConfig.jsp

import java.util.Set;

import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;

public class SocketConfig implements ServerApplicationConfig{

	@Override
	public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> arg0) {
		
		System.out.println("socket:"+arg0);
		//返回值是必須的
		return arg0;
	}

	@Override
	public Set<ServerEndpointConfig> getEndpointConfigs(
			Set<Class<? extends Endpoint>> arg0) {
		return null;
	}

}

EchoSocket.java

import java.io.IOException;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
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.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import com.czy.test.Messge;
import com.czy.test.vo;
import com.google.gson.Gson;
import com.sun.xml.internal.bind.v2.runtime.output.Encoded;

@ServerEndpoint("/echoSocket")
public class EchoSocket {
	//是用來記錄有多少websocket有多少session在執行
	private static List<Session> sessions = new ArrayList<Session>();
	//用來記錄有多少個使用者使用該websocket通道
	private static List<String> usernames = new ArrayList<String>();
	//用來記錄使用者名稱和該session進行繫結
	private static Map<String,Session> map = new HashMap<String, Session>();
	private String username;
	private Gson gson = new Gson();
	
	//開啟連結
	@OnOpen
	public void open(Session session){
//		sessions.add(session);
		String str = session.getQueryString();//可以得到ws://路徑?後面的所有字串
		username = str.split("=")[1];
		try {
			username = URLDecoder.decode(username, "utf-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		usernames.add(username);
		map.put(username, session);
		Messge msg = new Messge();
		msg.setWelcome("歡迎"+username+":進入聊天室");
		msg.setUsernames(usernames);
		broadSend(sessions, msg.toJson());
	}
	
	//關閉連線
	@OnClose
	public void close(Session session){
		System.out.println(session.getId()+":已經關閉");
		String str = session.getQueryString();
		username = str.split("=")[1];
		try {
			username = URLDecoder.decode(username, "utf-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		usernames.remove(username);
		sessions.remove(session);
		Messge msg = new Messge();
		msg.setExit(username+":離開聊天室");
		msg.setUsernames(usernames);
		broadSend(sessions, msg.toJson());
	}
	
	//客戶端和伺服器之間資訊處理
	@OnMessage
	public void sendMessage(Session session,String msg){
		vo v = gson.fromJson(msg,vo.class);
		System.out.println(v.toString());
		if (v.getType()==2) {
			Messge message = new Messge();
			message.setUsernames(usernames);
			message.setContent(v.getMsg(),username);
			broadSend(sessions,message.toJson());
		}else {
			//單聊
			Messge message = new Messge();
			String toUsername = v.getToUser();
			Session to_Session = map.get(toUsername);
			Session from_Session = map.get(username);
			message.setContent(v.getMsg(),v.getFromUser(),toUsername);
			System.out.println(message.toJson());
			try {
				to_Session.getBasicRemote().sendText(message.toJson());
				from_Session.getBasicRemote().sendText(message.toJson());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
	
	//實現群聊
	public void broadSend(List<Session> ss,String msg){
		for (Session session : ss) {
			try {
				session.getBasicRemote().sendText(msg);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

Messge.java是為了傳送到客戶端後資訊格式好看,而封裝的javabean

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.json.JSONArray;

import com.google.gson.Gson;

public class Messge {
	
	private List<String> usernames;
	private String content;
	private String username;
	private String welcome;
	private String exit;
	private Gson gson = new Gson();
	
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getWelcome() {
		return welcome;
	}
	public void setWelcome(String welcome) {
		this.welcome = welcome;
	}
	public String getExit() {
		return exit;
	}
	public void setExit(String exit) {
		this.exit = exit;
	}
	public List<String> getUsernames() {
		return usernames;
	}
	public void setUsernames(List<String> usernames) {
		this.usernames = usernames;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public void setContent(String msg,String username) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		date.getTime();
		String dateStr = sdf.format(date);
		String content = dateStr+" "+username+"說:"+"<br>"+msg;
		this.content = content;
	}
	
	public void setContent(String msg, String username, String toUsername) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = new Date();
		date.getTime();
		String dateStr = sdf.format(date);
		String content = dateStr+" "+username+"對"+toUsername+"說:"+"<br>"+msg;
		this.content = content;
	}
	
	public String toJson(){
		return gson.toJson(this);
	}
}
vo.java為了封裝echo.jsp頁面傳來的json函式

public class vo {
	private int type;
	private String toUser;
	private String msg;
	private String fromUser;
	
	public String getFromUser() {
		return fromUser;
	}
	public void setFromUser(String fromUser) {
		this.fromUser = fromUser;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public String getToUser() {
		return toUser;
	}
	public void setToUser(String toUser) {
		this.toUser = toUser;
	}
	public String getMsg() {
		return msg;
	}
	public void setMsg(String msg) {
		this.msg = msg;
	}
	@Override
	public String toString() {
		return "vo [type=" + type + ", toUser=" + toUser + ", msg=" + msg
				+ ", fromUser=" + fromUser + "]";
	}
}








相關文章