jsp 利用 websocket 做的多人聊天室

原文地址

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

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

运行结果图

前端代码:

 

<%@ 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

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基于Vue和WebSocket的多人在线聊天是一种使用Vue框架搭建前端,并利用WebSocket技术实现实时通信的应用程序。在这个聊天中,多个用户可以实时地发送和接收消息。 首先,使用Vue框架搭建前端界面。Vue框架提供了组件化的开发方式,可以方便地构建用户界面。通过Vue的指令和绑定,构建出聊天界面,包括用户列表、消息展示区和输入框。 然后,利用WebSocket技术实现实时通信。WebSocket是一种双向通信协议,可以在客户端和服务器之间建立持久的连接。在Vue中,可以使用WebSocket API来连接到服务器,并监听服务器发送的消息。当用户发送消息时,Vue会将消息发送给服务器,服务器再将消息广播给其他在线用户,实现多人聊天。 在聊天中,用户可以实时看到其他用户发送的消息,并且可以即时回复。聊天还可以提供其他功能,如图片和文件的发送与接收,表情的使用等。通过Vue的双向数据绑定,用户可以实时看到聊天的最新状态。 为了保证安全性,可以使用一些认证和授权的机制。例如,用户在进入聊天之前需要登录或注册,并提供有效的凭证。在服务器端,可以对每个连接进行身份认证,并进行权限控制,确保只有合法的用户可以参与聊天。 基于Vue和WebSocket的多人在线聊天可以提供实时的通信功能,使用户可以方便地进行多人聊天和交流。这个应用程序可以在各种场景下使用,如团队协作、在线教育等,增加信息共享和沟通效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值