websocket发送消息

Reads: 1138 Edit

WSServer


package com.mqtt.netty2;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class WSServer {

	public static void main(String[] args) throws InterruptedException {
		EventLoopGroup mainGroup = new NioEventLoopGroup();
		EventLoopGroup subGroup = new NioEventLoopGroup();

		try {
			ServerBootstrap serverBootstrap = new ServerBootstrap();
			serverBootstrap.group(mainGroup, subGroup)
				.channel(NioServerSocketChannel.class)
				.childHandler(new WSServerInitializer());

			ChannelFuture future = serverBootstrap.bind(8088).sync();
			future.channel().closeFuture().sync();
		} finally {
			mainGroup.shutdownGracefully();
			subGroup.shutdownGracefully();
		}

	}

}

WSServerInitializer

package com.mqtt.netty2;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;

public class WSServerInitializer extends ChannelInitializer<SocketChannel> {

	@Override
	protected void initChannel(SocketChannel ch) throws Exception {
		ChannelPipeline pipeline = ch.pipeline();
		// websocket基于http协议,所以要有http编解码器
		pipeline.addLast(new HttpServerCodec());
		// 对写大数据流的支持
		pipeline.addLast(new ChunkedWriteHandler());
		// 设置聚合器
		pipeline.addLast(new HttpObjectAggregator(1024 * 64));

		//====================== 以上是用于支持http协议 =====================
		
		// websocket 服务器处理的协议,用于指定给客户端连接访问的路由
		pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
		
		pipeline.addLast(new ChatHandler());
		
		
	}

}

ChatHandler

package com.mqtt.netty2;

import java.time.LocalDateTime;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * 处理消息的handler
 * TextWebSocketFrame 在netty中,用於為websocket專門用於處理文本的對象
 * */
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{
	//用于记录和管理所有客户端的 channel
	private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
	
	@Override
	protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
		// 获取客户端传输过来的消息
		String content =  msg.text();
		System.out.println("接收到的数据:" + content);
		
		// 第一種方法
//		for(Channel channel: clients) {
//			channel.writeAndFlush(
//					new TextWebSocketFrame("[服务器接收到消息:]" + 
//							LocalDateTime.now() + "接收到消息:" + content ));
//		}
		
		// 第二種方法
		clients.writeAndFlush(new TextWebSocketFrame("[服务器接收到消息:]" + 
							LocalDateTime.now() + "接收到消息:" + content ));
		
		
	}

	@Override
	public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
		// 當客戶端連接服務器端之後,獲取客戶端的channel,並且放到channelGroup中去進行管理
		clients.add(ctx.channel() );
	}

	@Override
	public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
		// 當触发handleReomved,ChannelGroup会自动移除对应客户端的channel
		clients.remove(ctx.channel());
		System.out.println("客戶端断开,channel对应的長id"+ctx.channel().id().asLongText());
		System.out.println("客戶端断开,channel对应的短id" +ctx.channel().id().asShortText());
	}
	
}

页面

在hbuilder 新建页面 index.html

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div>发送消息</div>
		<input type="text" id="msgContent"/>
		<input type="button"  value="发送" onclick="CHAT.chat()"  />
		
		<div>接收消息:</div>
		<div id="recciveMsg" style="background-color: yellow;">
			
			
		</div>
		
		<script type="application/javascript">
			window.CHAT = {
				socket : null,
				init: function(){
					if(window.WebSocket){
						CHAT.socket = new WebSocket("ws://127.0.0.1:8088/ws");
						CHAT.socket.onopen = function(){
							console.log("连接建立成功");
						},
						CHAT.socket.onclose = function(){
							console.log("连接关闭...");
						},
						CHAT.socket.onerror = function(){
							console.log("发生错误...");
						},
						CHAT.socket.onmessage = function(e){
							console.log("接收到消息:" + e.datta );
							var recciveMsg = document.getElementById("recciveMsg");
							var html = recciveMsg.innerHTML;
							recciveMsg.innerHTML = html + "<br/>" + e.data 
						}
						
					}else{
						alert("浏览器不支持websocket协议");
					}
				},
				chat: function(){
					var msg = document.getElementById("msgContent");
					CHAT.socket.send(msg.value);
					
				}
			}
			
			CHAT.init();
			
			
			
		</script>
	</body>
</html>

11127

心跳

关于作者

王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。


Comments

Make a comment

www.ultrapower.com ,王硕的博客,专注于研究互联网产品和技术,提供中文精品教程。 本网站与其它任何公司及/或商标无任何形式关联或合作。