侧边栏壁纸
博主头像
王小木人

这是很长,很好的一生

  • 累计撰写 141 篇文章
  • 累计创建 43 个标签
  • 累计收到 7 条评论

目 录CONTENT

文章目录

jsp 利用 websocket 做的多人聊天室

王小木人
2021-05-26 / 0 评论 / 0 点赞 / 1,698 阅读 / 6,360 字

聊天室演示地址
使用jsp做一个聊天室,一开始想到做一个聊天室时本想使用udp或是tcp发送数据包实现,使用线程来接收,但是做到最后,在获取到数据怎么实时的显示到浏览器呢,这种在客户端程序或许比较使用,但在web并不好交互,怎么想都不好实现,于是查看别人例子,发现通过websocket可以很好的实现,websocket逆向思维,一般都是由客户端发送请求到服务器,再有服务器发送响应到客户端,而客户端和服务器端建立了websocket连接后,允许服务器直接发送消息给客户端,以此实现web端实时接收来自服务器的数据,   WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议

那么聊天室的大致实现思路是这样的,,客户端和服务器端建立了websocket连接后,只要服务器接收到来自客户端的消息,就把收到的消息转发给所有的客户端,当然可以筛选下,不要发给自己本身,总的来说就是使用服务器做中转。

运行结果图
1.png
前端代码:

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<%
		String userName = request.getParameter("name");
		if (userName != null) {
		 session.setAttribute("userName", userName);
		 response.sendRedirect("Chat-room.jsp");
		}
	%>
	<form id="myform" action="index.jsp" method="post">
		姓名:<input id="name" name="name" type="text" /><input type="submit" value="开始聊天" />
	</form>
	<script>
	    document.getElementById('myform').onsubmit=function()
	    {
	    	return fun();
	    }
	    function fun()
	    {
	    	if(document.getElementById('name').value=="")
	    		return false;
	    	return true;
	    }
	</script>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="css/style.css" />
<script src="scripts/jquery-3.3.1.min.js" type="text/javascript"></script>
<script type="text/javascript">
	function setReceiver(obj) {
		document.getElementById("reply-to").innerHTML = "接收人:" + obj.innerHTML;
	}
</script>
</head>
<body>
	<div id="chat-room">
		<div class="lefter">
			<h2>在线用户列表</h2>
			<ul id="userlist">
 
			</ul>
		</div>
		<div class="righter">
			<div id="history">
			
			</div>
			<div class="spacer"></div>
			<div id="reply-to">接收人:所有  <span id="message"></span></div>
			<div class="reply">
			   <input id="username" hidden="hidden" value=<%=new String(session.getAttribute("userName").toString().getBytes("iso-8859-1"),"utf-8")%> type="text"/>
				   <input type="text" class="text" id="sendmessage" name="content" /><label
					class="ui-blue"><input type="button" id="sendbtn" value="发送" /></label>
			</div>
		</div>
	</div>
	<script type="text/javascript">
		setInterval("getuser()", 50)
		function getuser() {
			$.ajax({
				type:'get',
				url:'RoomUser',
				async:false,
				error:function(data){
					alert('发生错误');
				},
				success:function(data){
					$('#userlist').html(data);
				}
				
			});
		}
		
		 var websocket = null;
		    var userName =document.getElementById('username').value;
		    //判断当前浏览器是否支持WebSocket
		    if ('WebSocket' in window) {
		        websocket = new WebSocket("ws://localhost:8080/Chat/websocket?username="+userName);
		    }
		    else {
		        alert('当前浏览器 Not support websocket')
		    }
 
		    //连接发生错误的回调方法
		    websocket.onerror = function () {
		        setMessageInnerHTML("WebSocket连接发生错误");
		    };
 
		    //连接成功建立的回调方法
		    websocket.onopen = function () {
		        setMessageInnerHTML("连接成功,可以开始聊天了");
		    }
 
		    //接收到消息的回调方法
		    websocket.onmessage = function (event) {
		    	    document.getElementById('history').innerHTML+= "<p style='float:left'>"+event.data+"</p></br>";
		        
		    }
 
		    //连接关闭的回调方法
		    websocket.onclose = function () {
		        setMessageInnerHTML("WebSocket连接关闭");
		    }
 
		    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
		    window.onbeforeunload = function () {
		        closeWebSocket();
		    }
 
		    //将消息显示在网页上
		    function setMessageInnerHTML(innerHTML) {
		        document.getElementById('message').innerHTML= innerHTML + '<br/>';
		    }
 
		    //关闭WebSocket连接
		    function closeWebSocket() {
		        websocket.close();
		    }
		    document.getElementById("sendbtn").onclick=function(){
		    	  var message = document.getElementById('sendmessage').value;
		    	  document.getElementById('sendmessage').value="";
		          websocket.send(message);
		          document.getElementById('history').innerHTML+= "<p style='float:right'>我说:"+message+"</p></br>";
		    };
	</script>
</body>
</html>

后台代码

package com.websocket;
 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Set;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
 
/**
 * @ServerEndpoint 注解标识该类是websocket类
 */
@ServerEndpoint("/websocket")
public class WebSocketTest {
 
   //将用户的名字和每个websocket连接存在map集合中,static修饰,其他类可以直接调用
	private static HashMap<String, WebSocketTest> webSocketMap = new HashMap<String, WebSocketTest>();
 
   //session保存用户请求过来的信息
	private Session session;
	private String userName;
 
	/**
	 *
	 * 
	 * @param session
	 * 当有客户端与服务器建立连接时调用
	 */
	@OnOpen
	public void onOpen(Session session) {
		this.session = session;
		try {
			this.userName = URLDecoder.decode(session.getQueryString().substring(session.getQueryString().indexOf("=") + 1),"UTF-8");
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		webSocketMap.put(this.userName, this); //加入用户姓名和此连接
 
		
	}
 
	/**
	 *与服务器连接关闭时调用
	 */
	@OnClose
	public void onClose() {
		webSocketMap.remove(this.userName);
		
	}
 
	/**
	 *
	 * 
	 * @param message 
	 * @param session
	 * 收到来自客户端的消息时调用,session保存发送消息的客户端信息
	 */
	@OnMessage
	public void onMessage(String message, Session session) {
		String messageUser=null;
		try {
			messageUser = URLDecoder.decode(session.getQueryString().substring(session.getQueryString().indexOf("=") + 1), "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
	
		// Ⱥ����Ϣ
		Set<String> keys = webSocketMap.keySet();
		for (String key : keys) {
			if (!key.equals(messageUser)) {
				try {
					webSocketMap.get(key).sendMessage(messageUser+"说:"+message);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					continue;
				}
			}
		}
 
	}
 
	/**
	 *发生错误时调用
	 * 
	 * @param session
	 * @param error
	 */
	@OnError
	public void onError(Session session, Throwable error) {
	
		error.printStackTrace();
	}
 
 
	public void sendMessage(String message) throws IOException {
		this.session.getBasicRemote().sendText(message);
		// this.session.getAsyncRemote().sendText(message);
	}
 
 
	public static synchronized Set<String> getUser() {
		
		return webSocketMap.keySet();
 
	}
 
}
package com.servlet;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Set;
 
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
 
import com.websocket.WebSocketTest;
 
@WebServlet("/RoomUser")
public class RoomUser extends HttpServlet {
	private static final long serialVersionUID = 1L;
    //前台调用此方法获取在线用户列表
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=UTF-8");
		Set<String> users = WebSocketTest.getUser();
		StringBuffer str = new StringBuffer();
		for (String username : users) {
			str.append("<li><a href=# onclick=setReceiver(this)>" + username + "</a></li>");
 
		}
		PrintWriter out=response.getWriter();
	
		out.println(str);
	}
 
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
 
	}
 
}

最后附上下载地址:https://github.com/378526425/ChatRoom

0

评论区