【Netty】实现Netty4的web socket服务,比如聊天室的原型

欢迎转载,随便转载,从这里开始复制

arctan90


业务需要实现一个web socket,没考虑Tomcat,Tomcat那个容量简直惨不忍睹,居然还有人推荐用。

基本是照着官方样例来的:

server入口

http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServer.html

服务加载的channel生成器

http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServerInitializer.html


在pipeline上加载的Handler,这个Handler用来分离http和ws,在这个样例中,请求的ws地址是ws://localhost:port/websocket

http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketIndexPageHandler.html

在这个Handler中用到一个辅助类WebSocketServerIndexPage也要加载到项目中

http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketServerIndexPage.html


另一个Handler处理websocket消息

http://netty.io/4.0/xref/io/netty/example/http/websocketx/server/WebSocketFrameHandler.html

这个Handler需要改造一下,样例只能自娱自乐,因为他在channelRead0的时候直接向ChannelHandlerContext回写

我需要一个聊天室的话,需要另外一个group,引入一个帮助类

Global.java

import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;
public class Global {
    public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
} 


修改一下WebSocketFrameHandler的实现,在channelRead0()里面,把读到的数据写到上面的那个实例化的group里面。

在context激活的时候(web socket建立完成),把channel加到group,在context注销的时候(web socket关闭) 把group从channel中移除。

import io.netty.channel.ChannelHandlerContext;

import io.netty.channel.SimpleChannelInboundHandler;

import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import io.netty.handler.codec.http.websocketx.WebSocketFrame;


public class WebSocketFrameHandler extends SimpleChannelInboundHandler{


    @Override

    protected void channelRead0(ChannelHandlerContextctx, WebSocketFrameframe) throws Exception {

        // TODO Auto-generated method stub

        if (frameinstanceof TextWebSocketFrame) {

            String request = ((TextWebSocketFrame)frame).text();

            System.out.println(request);

            //ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));

            Global.group.writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.CHINA)));

        } else {

            String message = "unsupported frame type: " + frame.getClass().getName();

            System.out.println(message);

        }

    }


    @Override

    public void channelUnregistered(ChannelHandlerContextctx) throws Exception {

        Global.group.remove(ctx.channel());

    }


    @Override

    public void channelActive(ChannelHandlerContextctx) throws Exception {

        Global.group.add(ctx.channel());

    }

    @Override

    public void exceptionCaught(ChannelHandlerContextctx, Throwable cause)throws Exception {

        // TODO Auto-generated method stub

        //cause.printStackTrace();

        ctx.close(); //出异常的时候关闭channel

    }

}


你可能感兴趣的:(netty)