(3)websocket實現單聊和群聊
阿新 • • 發佈:2019-01-06
2 群聊圖
2.1 zhangsan 發給所有人的圖
2.2 傳送成功後
zhangsan的介面如下
lisi的介面如下
wangwu的介面如下
3 單聊圖
3.1 zhangsan傳送資訊圖如下
3.2傳送成功後
zhangsan介面如下
lisi介面如下
wangwu介面如下
4 專案結構圖
5 程式碼
5.1 ChartMessage.java
package com.web.message; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import com.google.gson.Gson; public class ChartMessage { private int type; // 單聊 type = 1 ,type =2 群聊 private String from; //由誰發的 private List<String> to; //發給誰 private String content; //聊天內容 private String welcome; //進聊天室和離開聊天室提示資訊 private List<String> usernames ; //使用者列表名字 private List<String> sessionUsernames;//websocket session名字 private static Gson gson = new Gson(); public ChartMessage(){ } public ChartMessage(String welcome,List<String> usernames ){ this.welcome = welcome; this.usernames = usernames; } public int getType() { return type; } public void setType(int type) { this.type = type; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public List<String> getTo() { return to; } public void setTo(List<String> to) { this.to = to; } public String getContent() { return content; } public void setContent(String content) { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String time = sdf.format(new Date()); this.content = "\r\n\r\n" +time +"\r\n" +from+" said : " + content; } public String getChartMessageToJson(){ return gson.toJson(this); } public List<String> getUsernames() { return usernames; } public void setUsernames(List<String> usernames) { this.usernames = usernames; } public String getWelcome() { return welcome; } public void setWelcome(String welcome) { this.welcome = welcome; } public List<String> getSessionUsernames() { return sessionUsernames; } public void setSessionUsernames(List<String> sessionUsernames) { this.sessionUsernames = sessionUsernames; } }
5.2 Login.java
package com.web.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Login extends HttpServlet { /** * Constructor of the object. */ public Login() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // System.out.println("username = " + username); request.setAttribute("username", username); RequestDispatcher dispatcher = request.getRequestDispatcher("/chart.jsp"); dispatcher.forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
5.3 EchoSocket.java
5.4package com.webSocket.client; import java.io.IOException; import java.util.ArrayList; 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 net.sf.json.JSONArray; import net.sf.json.JSONObject; import com.web.message.ChartMessage; @ServerEndpoint("/echo") public class EchoSocket { private static List<String> usernames = new ArrayList<String>(); private static List<Session> sessions = new ArrayList<Session>(); private static Map<String,Session> sessionMap = new HashMap<String,Session>(); private String username; private Session session; @OnOpen public void open(Session session){ //開啟websocket System.out.println("userid = "+session.getId()); String string = session.getQueryString(); this.username = string.split("=")[1]; this.usernames.add(this.username); this.sessions.add(session); sessionMap.put(this.username, session); String welcome = "歡迎"+this.username+"加入聊天室"; ChartMessage message = new ChartMessage(welcome,this.usernames); this.broadcast(this.sessions,message.getChartMessageToJson()); } @OnClose public void close(Session session){ //關閉websocket this.sessions.remove(session); this.usernames.remove(this.username); String goMsg = this.username+"已經離開聊天室"; ChartMessage message = new ChartMessage(goMsg,this.usernames); sessionMap.remove(this.username); this.broadcast(this.sessions,message.getChartMessageToJson()); System.out.println("websocket is close"); } @OnMessage public void message(Session session,String msg){ if (session.isOpen()) { JSONObject msgJsonObj = JSONObject.fromObject(msg); ChartMessage chartMessage = (ChartMessage) JSONObject.toBean(msgJsonObj, ChartMessage.class); chartMessage.setUsernames(this.usernames); if(chartMessage.getType() == 1){ // type =1 單聊 List<Session> sessionsPrivateList = new ArrayList<Session>(); for(int i = 0 ; i <chartMessage.getTo().size() ; i++){ String userChartName = chartMessage.getTo().get(i); sessionsPrivateList.add(sessionMap.get(userChartName)); } sessionsPrivateList.add(sessionMap.get(chartMessage.getFrom())); this.broadcast(sessionsPrivateList,chartMessage.getChartMessageToJson()); }else if(chartMessage.getType() == 2){ // type = 2 群聊 this.broadcast(this.sessions,chartMessage.getChartMessageToJson()); } } } public List<String> getUsernames() { return usernames; } public List<Session> getSessions() { return sessions; } private void broadcast(List<Session> sessionsList,String msg) { //廣播給其它人 if(sessionsList.size() > 0){ for(int i = 0 ; i < sessionsList.size() ; i++){ try { sessionsList.get(i).getBasicRemote().sendText(msg); } catch (IOException e) { System.out.println("EchoSocket.java broadcast method ,廣播失敗 "); e.printStackTrace(); } } } } }
DemeConfig.java
package com.webSocket.config;
import java.util.Set;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
public class DemeConfig implements ServerApplicationConfig{
//註解的方式 啟動
public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {
System.out.println("-------------websoket start-----------------");
System.out.println("scan.size() = " + scan.size());
return scan; //必須要返回scan,否則會造成連線失敗
}
//介面方式啟動
public Set<ServerEndpointConfig> getEndpointConfigs(
Set<Class<? extends Endpoint>> arg0) {
return null;
}
}
5.5 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>Login</servlet-name>
<servlet-class>com.web.servlet.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/servlet/Login</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
5.6 chart.jsp
<%@ page language="java" import="java.util.*,javax.*" 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>
<title>My JSP 'index.jsp' starting page</title>
</head>
<body>
<script type="text/javascript">
var ws=null;
var target = "ws://"+window.location.host+"/webSocketTest/echo?username=${requestScope.username}"; // 開啟管道 ,ws://localhost:8080/專案名/@ServerEndpoint名字
window.onload=function(){
if(ws==null){
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;
}
ws.onmessage = function (event) { //建立websocket同時,接收伺服器發給客服端的訊息
if(event!=null){
//將json字串轉為物件
eval("var msg="+event.data+";");
//得到物件裡面的值
var welcome = msg.welcome;
var content = msg.content;
var usernames = msg.usernames;
//為聊天區teaxarea賦值
var textArea = document.getElementById("content");
if(undefined!=welcome){
textArea.value = textArea.value + "\r\n"+welcome;
}
if(undefined!=content){
textArea.value = textArea.value + "\r\n"+content;
}
//為使用者列表區TD賦值
var userListTD = document.getElementById("userList");
userListTD.innerHTML="";
for(var i = 0 ; i < usernames.length; i++){
if(undefined!=usernames[i]){
if("${requestScope.username}" == usernames[i]){
userListTD.innerHTML += "\r\n <input name='msgCheckBox' disabled='true' type='checkbox' value='"+usernames[i]+"'> <span style='color: red'>" + usernames[i]+"</span></br>";
}else{
userListTD.innerHTML += "\r\n <input name='msgCheckBox' type='checkbox' value='"+usernames[i]+"'>" + usernames[i]+"</br>";
}
}
}
}
};
}
};
sendMessage = function(){ //傳送資訊
if(ws!=null){
var checkNumber = 0 ; // 被選中複選框的個數
var checkedUsernameArray = new Array(); // 被選中的複選框名字
var checkBoxs = document.getElementsByName("msgCheckBox");
for(var i = 0 ; i < checkBoxs.length ; i++ ){
var checkbox = checkBoxs[i];
if(checkbox.checked == true){
checkNumber ++;
checkedUsernameArray.push(checkbox.value) ;
}
}
// alert("checkedUsernameArray = " + checkedUsernameArray);
var type; // 單聊 type = 1 ,type =2 群聊
if(checkNumber > 0 ) { // 單聊 type = 1
type = 1;
}else{ //群聊
type = 2;
}
var sendMessageInput = document.getElementById("sendMessageTextArea");
var msg = sendMessageInput.value;
/*
1 傳送物件有哪些
2 傳送的型別 單聊/群聊
3 內容
*/
var msgObj={
type:type,
from:'${requestScope.username}',
to:checkedUsernameArray,
content:msg
};
//將msgOjb物件轉為json
var json = JSON.stringify(msgObj);
ws.send(json);
sendMessageInput.value ="";
}
else{
alert("websocket is null , please create a websocket");
}
}
</script>
<table cellpadding="0" cellspacing="0" border="1" width="500px" height="400px">
<tr>
<td>
<textarea id="content" rows="10" cols=50">
</textarea>
</td>
<td id="userList" width="150px" align="center">
</td>
</tr>
<tr>
<td colspan="2">
<textarea id="sendMessageTextArea" rows="5" cols=50">
</textarea>
<button onclick="sendMessage()">傳送</button>
</td>
</tr>
</table>
</body>
</html>
5.7 login.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>
<title>login</title>
</head>
<body>
<form action="<%=request.getContextPath()%>/servlet/Login" method="get">
使用者名稱:<input type="text" name="username"/>
<input type="submit" value="登入"/>
</form>
</body>
</html>