基于spring4 websocket的简易聊天室

一:创建maven webapp项目

编辑pom.xml文件

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

	<modelVersion>4.0.0</modelVersion>
	<groupId>com.lala</groupId>
	<artifactId>tweet</artifactId>
	<version>1.0.0</version>
	<packaging>war</packaging>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<jsp.version>2.2</jsp.version>
		<jstl.version>1.2</jstl.version>
		<servlet.version>3.0.1</servlet.version>
		<spring-framework.version>4.1.7.RELEASE</spring-framework.version>
		<junit.version>4.12</junit.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>${jstl.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>${servlet.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>${jsp.version}</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-websocket</artifactId>
			<version>${spring-framework.version}</version>
		</dependency>
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.3.1</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.3</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
					<verbose>true</verbose>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.eclipse.jetty</groupId>
				<artifactId>jetty-maven-plugin</artifactId>
				<version>9.2.11.v20150529</version>
				<configuration>
					<stopKey>foo</stopKey>
					<stopPort>9999</stopPort>
					<httpConnector>
						<port>9090</port>
					</httpConnector>
					<webApp>
						<contextPath>/</contextPath>
					</webApp>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>


二:编写server endpoint

package com.lala.action;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import com.google.gson.Gson;

public class TweetWebSocket extends TextWebSocketHandler
{
	private Map<String, WebSocketSession> clients = new ConcurrentHashMap<>();
	
	public void handleTextMessage(WebSocketSession session, TextMessage message)
	{
		if(!clients.containsKey(session.getId()))
		{
			clients.put(session.getId(), session);
		}
		String data = message.getPayload();
		
		Gson g = new Gson();
		Map<String, Object> datas = g.fromJson(data, Map.class);
		String type = datas.get("type").toString();
		
		if("1".equals(type))
		{
			datas.put("pcount", clients.keySet().size() + "");
		}
		else if("3".equals(type))
		{
			clients.remove(session.getId());
			datas.put("pcount", clients.keySet().size() + "");
		}
		
		TextMessage tm = new TextMessage(g.toJson(datas));
		sendToAll(tm);
	}
	private void sendToAll(TextMessage tm)
	{
		try
		{
			for(WebSocketSession session : clients.values())
			{
				if(session.isOpen())
				{
					session.sendMessage(tm);
				}
				else
				{
					clients.remove(session.getId());
				}
			}
		}catch(Exception e)
		{
			e.printStackTrace();
		}
	}
}

三:mvn-servlet配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	   xmlns:mvc="http://www.springframework.org/schema/mvc" 
	   xmlns:context="http://www.springframework.org/schema/context"
	   xmlns:websocket="http://www.springframework.org/schema/websocket"
	   xsi:schemaLocation="http://www.springframework.org/schema/mvc 
	   http://www.springframework.org/schema/mvc/spring-mvc.xsd
	   http://www.springframework.org/schema/beans 
	   http://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/websocket
       http://www.springframework.org/schema/websocket/spring-websocket.xsd
	   http://www.springframework.org/schema/context 
	   http://www.springframework.org/schema/context/spring-context.xsd">
	   
    <mvc:annotation-driven />
    
    <context:component-scan base-package="com.lala"></context:component-scan>

	<bean id="tweet" class="com.lala.action.TweetWebSocket"/>

	<websocket:handlers>
        <websocket:mapping path="/tweets/list" handler="tweet"/>
    </websocket:handlers>

	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"/>
        <property name="suffix" value=".jsp"/>
	</bean>
	
</beans>


index.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>动弹列表</title>
<script src="http://libs.baidu.com/jquery/1.9.0/jquery.js"></script>
<style type="text/css">
	.jz {
		margin: 0 auto; 
		text-align: center;
	}
	.tw {
		border:1px dotted red;
		height: 60px;
		width:600px;
		margin:0px auto;
		padding-left:10px;
		padding-top:10px;
		margin-top:5px;
	}
	.top {
		
	}
	.buttom {
		padding-top:10px;
	}
	#send-box {
		margin-top:10px;
	}
</style>
</head>
<body>
<div class="jz" style="font-size:30px;">动弹列表</div>
<div class="jz" style="font-size:20px;">欢迎回来:${param.username},当前在线人数<b id="pcount"></b></div>
<div class="jz" id="err-box"></div>
<div id="msg-box">
	<div class="tw">
		<div class="top">admin  2015-07-05</div>
		<div class="buttom">请大家随意畅谈</div>
	</div>
</div>
<div id="send-box" class="jz">
	<input type="text" id="text-msg" style="width:300px;"/>
	<input type="button" οnclick="send_msg()" value="发布动弹"/>
</div>
<script type="text/javascript">
	var username = '${param.username}';
	var ws = new WebSocket('ws://127.0.0.1:9090/tweets/list');

	ws.onerror = function(event)
	{
		$('#err-box').html(event);
	};

	ws.onopen = function(event) 
	{
		start() ;
	};
	
	ws.onclose = function(event) { 
		var msg = JSON.stringify({'username':username, 'type':'3'});  
		ws.send(msg);
	}; 

	ws.onmessage = function(event) 
	{
		var data = JSON.parse(event.data);
		if(data.type == '2')
		{
			render_data(data.username, data.data);
		}
		else if(data.type == '1')
		{
			$('#pcount').html(data.pcount);
			render_data('<span style="color:red;">系统信息</span>', data.username + "加入系统");
		}
	};

	function render_data(username, data)
	{
		var msg = [];
		msg.push('<div class="tw">');
		msg.push('<div class="top">' + username + '  2015-07-05</div>');
		msg.push('<div class="buttom"> ' + data + ' </div>');
		msg.push('</div>');
		$('#msg-box').append(msg.join(''));
	}
	
	function start() 
	{
		if(username != '')
		{
			var msg = JSON.stringify({'username':username, 'type':'1'});  
			ws.send(msg);
		}
	}

	function send_msg()
	{
		var text_msg = $('#text-msg').val();
		if(text_msg != '')
		{
			var msg = JSON.stringify({'username':username, 'type':'2', 'data': text_msg});  
			ws.send(msg);
			$('#text-msg').val('');
		}
	}
	
	(function(){
		if(username == '')
		{
			alert('用户名为空,无法发布动弹');
			$('#send-box').hide();
		}
	})();
</script>
</body>
</html>


最后,执行

mvn clean jetty:run

启动服务

在浏览器上面输入

http://127.0.0.1:9090/index.jsp?username=用户名

多开几个浏览器窗口,即可群聊


效果图为:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值