Netty4实现Websocket网页间聊天

理解了Netty的流程后,代码还是比较容易理解的,直接贴出代码

主启动程序:

public class ChatServer {
	private final ChannelGroup group = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE);

	private final EventLoopGroup workerGroup = new NioEventLoopGroup();

	private Channel channel;

	public ChannelFuture start(InetSocketAddress address){
		ServerBootstrap boot = new ServerBootstrap();
		boot.group(workerGroup).channel(NioServerSocketChannel.class).childHandler(createInitializer(group));

		ChannelFuture f = boot.bind(address).syncUninterruptibly();
		channel = f.channel();
		return f;
	}

	protected ChannelHandler createInitializer(ChannelGroup group2) {
		return new ChatServerInitializer(group2);
	}

	public void destroy(){
		if(channel != null)
			channel.close();
		group.close();
		workerGroup.shutdownGracefully();
	}

	public static void main(String[] args) {
		final ChatServer server = new ChatServer();
		ChannelFuture f = server.start(new InetSocketAddress(2048));
		System.out.println("server start................");
		Runtime.getRuntime().addShutdownHook(new Thread(){
			@Override
			public void run() {
				server.destroy();
			}
		});
		f.channel().closeFuture().syncUninterruptibly();
	}

}


初始化链:

public class ChatServerInitializer extends ChannelInitializer<Channel> {

	private final ChannelGroup group;
	public ChatServerInitializer(ChannelGroup group) {
		super();
		this.group = group;
	}

	@Override
	protected void initChannel(Channel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();

		pipeline.addLast(new HttpServerCodec());

		pipeline.addLast(new ChunkedWriteHandler());

		pipeline.addLast(new HttpObjectAggregator(64*1024));

		pipeline.addLast(new HttpRequestHandler("/ws"));

		pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

		pipeline.addLast(new TextWebSocketFrameHandler(group));

	}

}


HTTP请求处理:

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	private final String wsUri;
	public HttpRequestHandler(String wsUri) {
		super();
		this.wsUri = wsUri;
	}
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg)
			throws Exception {
		if(wsUri.equalsIgnoreCase(msg.getUri())){
			ctx.fireChannelRead(msg.retain());
		}else{
			if(HttpHeaders.is100ContinueExpected(msg)){
				FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.CONTINUE);
				ctx.writeAndFlush(response);
			}

			RandomAccessFile file = new RandomAccessFile(HttpRequestHandler.class.getResource("/").getPath()+"/index.html", "r");
			HttpResponse response = new DefaultHttpResponse(msg.getProtocolVersion(), HttpResponseStatus.OK);
			response.headers().set(HttpHeaders.Names.CONTENT_TYPE, "text/html;charset=UTF-8");

			boolean isKeepAlive = HttpHeaders.isKeepAlive(msg);
			if(isKeepAlive){
				response.headers().set(HttpHeaders.Names.CONTENT_LENGTH, file.length());
				response.headers().set(HttpHeaders.Names.CONNECTION, HttpHeaders.Values.KEEP_ALIVE);
			}

			ctx.write(response);
			if(ctx.pipeline().get(SslHandler.class) == null){
				ctx.write(new DefaultFileRegion(file.getChannel(), 0, file.length()));
			}else{
				ctx.write(new ChunkedNioFile(file.getChannel()));
			}

			ChannelFuture future = ctx.writeAndFlush(LastHttpContent.EMPTY_LAST_CONTENT);
			if(isKeepAlive == false){
				future.addListener(ChannelFutureListener.CLOSE);
			}

			file.close();
		}
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		ctx.close();
		cause.printStackTrace(System.err);
	}
}


websocket处理:

public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	private final ChannelGroup group;

	public TextWebSocketFrameHandler(ChannelGroup group) {
		super();
		this.group = group;
	}
	@Override
	public void userEventTriggered(ChannelHandlerContext ctx, Object evt)
			throws Exception {

		if(evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE){
			ctx.pipeline().remove(HttpRequestHandler.class);

			group.writeAndFlush(new TextWebSocketFrame("Client "+ctx.channel()+" joined!"));

			group.add(ctx.channel());
		}else{
			super.userEventTriggered(ctx, evt);
		}

	}

	@Override
	protected void channelRead0(ChannelHandlerContext ctx,
			TextWebSocketFrame msg) throws Exception {
		group.writeAndFlush(msg.retain());
	}
	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
			throws Exception {
		ctx.close();
		cause.printStackTrace();
	}
}


网页index.html代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<script type="text/javascript">
		var socket;
		if (!window.WebSocket) {
			window.WebSocket = window.MozWebSocket;
		}
		if (window.WebSocket) {
			socket = new WebSocket("ws://localhost:2048/ws");
			socket.onmessage = function(event) {
				var ta = document.getElementById(‘responseText‘);
				ta.value = ta.value + ‘\n‘ + event.data
			};
			socket.onopen = function(event) {
				var ta = document.getElementById(‘responseText‘);
				ta.value = "连接开启!";
			};
			socket.onclose = function(event) {
				var ta = document.getElementById(‘responseText‘);
				ta.value = ta.value + "连接被关闭";
			};
		} else {
			alert("你的浏览器不支持!");
		}

		function send(message) {
			if (!window.WebSocket) {
				return;
			}
			if (socket.readyState == WebSocket.OPEN) {
				socket.send(message);
			} else {
				alert("连接没有开启.");
			}
		}
	</script>
	<form onsubmit="return false;">
		<input type="text" name="message" value="Hello, World!"><input
			type="button" value="发送消息"
			onclick="send(this.form.message.value)">
		<h3>输出:</h3>
		<textarea id="responseText" style="width: 500px; height: 300px;"></textarea>
		<input type="button" onclick="javascript:document.getElementById(‘responseText‘).value=‘‘" value="清空">
	</form>
</body>
</html>


运行主程序后,在支持Websocket的浏览器中输入 : 127.0.0.1:2048   就可以打开聊天页面,打开多个页面,可以互相聊天。

项目已经打包上传,

项目地址:https://github.com/ivyboy/nettyWebsocket

时间: 2024-10-11 04:51:14

Netty4实现Websocket网页间聊天的相关文章

Websocket网页间聊天

主要使用Websocket来和服务端进行通讯,后端的技术使用什么,都可以,比如mina,netty4.... Netty4实现Websocket网页间聊天 地址:http://my.oschina.net/u/1756290/blog/363247 说明下:该技术只支持HTML5,该技术现阶段并不是很成熟

分享基于 websocket 网页端聊天室

博客地址:https://ainyi.com/#/67 有一个月没有写博客了,也是因为年前需求多.回家过春节的原因,现在返回北京的第二天,想想,应该也要分享技术专题的博客了!! 主题 基于 websocket 网页端聊天室 WebSocket 协议是基于 TCP 的一种新的网络协议.它实现了浏览器与服务器全双工 (full-duplex) 通信--允许服务器主动发送信息给客户端. 使用 java 开发后台 需要导入一个jar包:javax.websocket-api-1.0-rc4.jar 后台

Spring之WebSocket网页聊天以及服务器推送

Spring之WebSocket网页聊天以及服务器推送 转自:http://www.xdemo.org/spring-websocket-comet/ /Springframework /Spring之WebSocket网页聊天以及服务器推送 1. WebSocket protocol 是HTML5一种新的协议.它实现了浏览器与服务器全双工通信(full-duplex). 2. 轮询是在特定的的时间间隔(如每1秒),由浏览器对服务器发出HTTP request,然后由服务器返回最新的数据给客服端

使用PHP+Swoole实现的网页即时聊天工具:PHPWebIM

使用PHP+Swoole实现的网页即时聊天工具 全异步非阻塞Server,可以同时支持数百万TCP连接在线 同时支持websocket+comet2种兼容协议,可用于所有种类的浏览器包括IE 拥有完整的UI界面 支持单聊/群聊/组聊等功能 支持发送表情 支持永久保存聊天记录 基于Server PUSH的即时内容更新,登录/登出/状态变更/消息等会内容即时更新 最新的版本已经可以原生支持IE系列浏览器了,基于Http长连接 安装 swoole扩展 pecl install swoole swool

基于html5 localStorage , web SQL, websocket的简单聊天程序

new function() { var ws = null; var connected = false; var serverUrl; var connectionStatus; var sendMessage; var connectButton; var disconnectButton; var sendButton; var open = function() { var url = serverUrl.val(); ws = new WebSocket(url); ws.onope

HTML5 WebSocket实现点对点聊天的示例代码

HTML5的websocket与Tomcat实现了多人聊天,那是最简单也是最基本的,其中注意的就是开发环境,要满足jdk1.7和tomcat8,当然了tom7的7.063也行,在网站上找到了用google关于websocket的点对点聊天,更好的是可以和大多数系统很好的配合起来看下效果图. 因为是模拟的,这里给出的是两个JSP页面A和B,里面分别向session里放了两个名字小明和小化,注意,这里的session是HttpSessionsession,之前多人聊天里的session是javax.

SpringBoot+Vue+WebSocket 实现在线聊天

一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二.SpringBoot + Vue + WebSocket 实现在线聊天 1.引入websocket依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo

WebSocket 网页聊天室的实现(服务器端:.net + windows服务,前端:Html5)

websocket是HTML5中的比较有特色一块,它使得以往在客户端软件中常用的socket在web程序中也能轻松的使用,较大的提高了效率.废话不多说,直接进入题. 网页聊天室包括2个部分,后端服务器+前端页面. 1.后端服务部分:.net4.0 + windows服务.相比寄宿在iis中,寄宿在进程中的windows服务更加的稳定可靠(文章中的例子用windows控制台程序演示,后面给出完整的windows服务的代码). 2.前端部分:html5 + jQuery + bootstrap.基本

基于WebSocket实现网页版聊天室

WebSocket ,HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议,其使用简单,应用场景也广泛,不同开发语言都用种类繁多的实现,仅Java体系中,Tomcat,Jetty,Spring等都提供了对WS的API支持.本篇不做理论探究,仅自娱自乐,简单实现网页版的聊天室功能,在实际开发场景中变通使用即可.废话不叽歪,直接撸出来—— 1  简单页面 <!DOCTYPE html> <html lang="en"> <head> &l