Netty的websocket Demo
1.服務端
public final class WebSocketServer {
static final boolean SSL = System.getProperty("ssl") != null;
static final int PORT = Integer.parseInt(System.getProperty("port", SSL? "8443" : "8080"));
public static void main(String[] args) throws Exception {
// Configure SSL.
final SslContext sslCtx;
if (SSL) {
SelfSignedCertificate ssc = new SelfSignedCertificate();
sslCtx = SslContextBuilder.forServer(ssc.certificate(), ssc.privateKey()).build();
} else {
sslCtx = null;
}
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new WebSocketServerInitializer(sslCtx));
Channel ch = b.bind(PORT).sync().channel();
System.out.println("Open your web browser and navigate to " +
(SSL? "https" : "http") + "://127.0.0.1:" + PORT + '/');
ch.closeFuture().sync();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
public class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> {
private static final String WEBSOCKET_PATH = "/websocket";
private final SslContext sslCtx;
public WebSocketServerInitializer(SslContext sslCtx) {
this.sslCtx = sslCtx;
}
@Override
public void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
if (sslCtx != null) {
pipeline.addLast(sslCtx.newHandler(ch.alloc()));
}
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new HttpObjectAggregator(65536));
pipeline.addLast(new WebSocketServerProtocolHandler(WEBSOCKET_PATH, null, true));
pipeline.addLast(new WebSocketFrameHandler());
}
}
/**
* Echoes uppercase content of text frames.
*/
public class WebSocketFrameHandler extends SimpleChannelInboundHandler<WebSocketFrame> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception {
// ping and pong frames already handled
if (frame instanceof TextWebSocketFrame) {
// Send the uppercase string back.
String request = ((TextWebSocketFrame) frame).text();
System.out.println(ctx.channel()+" received" + request);
ctx.channel().writeAndFlush(new TextWebSocketFrame(request.toUpperCase(Locale.US)));
} else {
String message = "unsupported frame type: " + frame.getClass().getName();
throw new UnsupportedOperationException(message);
}
}
}
服務端的pipeline中新增了WebSocketServerProtocolHandler,支援websocket,這是最重要的一步。
2.java客戶端
public final class WebSocketClient {
static final String URL = System.getProperty("url", "ws://127.0.0.1:8080/websocket");
public static void main(String[] args) throws Exception {
URI uri = new URI(URL);
String scheme = uri.getScheme() == null? "ws" : uri.getScheme();
final String host = uri.getHost() == null? "127.0.0.1" : uri.getHost();
final int port;
if (uri.getPort() == -1) {
if ("ws".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("wss".equalsIgnoreCase(scheme)) {
port = 443;
} else {
port = -1;
}
} else {
port = uri.getPort();
}
if (!"ws".equalsIgnoreCase(scheme) && !"wss".equalsIgnoreCase(scheme)) {
System.err.println("Only WS(S) is supported.");
return;
}
final boolean ssl = "wss".equalsIgnoreCase(scheme);
final SslContext sslCtx;
if (ssl) {
sslCtx = SslContextBuilder.forClient()
.trustManager(InsecureTrustManagerFactory.INSTANCE).build();
} else {
sslCtx = null;
}
EventLoopGroup group = new NioEventLoopGroup();
try {
final WebSocketClientHandler handler =
new WebSocketClientHandler(
WebSocketClientHandshakerFactory.newHandshaker(
uri, WebSocketVersion.V13, null, false, new DefaultHttpHeaders()));
Bootstrap b = new Bootstrap();
b.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) {
ChannelPipeline p = ch.pipeline();
if (sslCtx != null) {
p.addLast(sslCtx.newHandler(ch.alloc(), host, port));
}
p.addLast(
new HttpClientCodec(),
new HttpObjectAggregator(8192),
handler);
}
});
Channel ch = b.connect(uri.getHost(), port).sync().channel();
handler.handshakeFuture().sync();
BufferedReader console = new BufferedReader(new InputStreamReader(System.in));
while (true) {
String msg = console.readLine();
if (msg == null) {
break;
} else if ("bye".equals(msg.toLowerCase())) {
ch.writeAndFlush(new CloseWebSocketFrame());
ch.closeFuture().sync();
break;
} else if ("ping".equals(msg.toLowerCase())) {
WebSocketFrame frame = new PingWebSocketFrame(Unpooled.wrappedBuffer(new byte[] { 8, 1, 8, 1 }));
ch.writeAndFlush(frame);
} else {
WebSocketFrame frame = new TextWebSocketFrame(msg);
ch.writeAndFlush(frame);
}
}
} finally {
group.shutdownGracefully();
}
}
}
public class WebSocketClientHandler extends SimpleChannelInboundHandler<Object> {
private final WebSocketClientHandshaker handshaker;
private ChannelPromise handshakeFuture;
public WebSocketClientHandler(WebSocketClientHandshaker handshaker) {
this.handshaker = handshaker;
}
public ChannelFuture handshakeFuture() {
return handshakeFuture;
}
@Override
public void handlerAdded(ChannelHandlerContext ctx) {
handshakeFuture = ctx.newPromise();
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
handshaker.handshake(ctx.channel());
}
@Override
public void channelInactive(ChannelHandlerContext ctx) {
System.out.println("WebSocket Client disconnected!");
}
@Override
public void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
Channel ch = ctx.channel();
if (!handshaker.isHandshakeComplete()) {
handshaker.finishHandshake(ch, (FullHttpResponse) msg);
System.out.println("WebSocket Client connected!");
handshakeFuture.setSuccess();
return;
}
if (msg instanceof FullHttpResponse) {
FullHttpResponse response = (FullHttpResponse) msg;
throw new IllegalStateException(
"Unexpected FullHttpResponse (getStatus=" + response.getStatus() +
", content=" + response.content().toString(CharsetUtil.UTF_8) + ')');
}
WebSocketFrame frame = (WebSocketFrame) msg;
if (frame instanceof TextWebSocketFrame) {
TextWebSocketFrame textFrame = (TextWebSocketFrame) frame;
System.out.println("WebSocket Client received message: " + textFrame.text());
} else if (frame instanceof PongWebSocketFrame) {
System.out.println("WebSocket Client received pong");
} else if (frame instanceof CloseWebSocketFrame) {
System.out.println("WebSocket Client received closing");
ch.close();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
if (!handshakeFuture.isDone()) {
handshakeFuture.setFailure(cause);
}
ctx.close();
}
}
3.js客戶端
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" charset="utf-8" >
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket){
alert("WebSocket not supported by this browser");
}
var websocket = new WebSocket("ws://127.0.0.1:8080/websocket");
websocket.onmessage = function(evt){
var data = evt.data;
alert("received message: " + data);
}
function send() {
var name = document.getElementById('name').value;
alert("websocket send message:"+name);
websocket.send(name);
}
</script>
</head>
<body>
<label for="name">What’s your name:</label>
<input type="text" id="name" name="name" id='name'/>
<button onclick="send()">Send</button>
<div id="message" style="color:red"></div>
</body>
</html>
相關文章
- 簡單的websocket demoWeb
- netty系列之:使用netty搭建websocket伺服器NettyWeb伺服器
- netty系列之:使用netty搭建websocket客戶端NettyWeb客戶端
- Netty 框架學習 —— 新增 WebSocket 支援Netty框架Web
- Netty從入門到禿頭: websocketNettyWeb
- 一個最簡單的WebSocket hello world demoWeb
- Spring Boot系列22 Spring Websocket實現websocket叢集方案的DemoSpring BootWeb
- WebSocket+Netty構建web聊天程式WebNetty
- swoole 的練習 demo(3)- 簡陋的 websocket 專案Web
- netty系列之:分離websocket處理器NettyWeb
- 從零開始netty學習筆記之netty簡單demoNetty筆記
- 從零學Netty(四)Reactor模式(含demo)NettyReact模式
- 從一個Demo開始,揭開Netty的神祕面紗Netty
- Netty+WebSocket 獲取火幣交易所資料專案NettyWeb
- 慕課網《Netty入門之WebSocket初體驗》學習總結NettyWeb
- WebSocket的故事(一)—— WebSocket的由來Web
- 基於Netty實現的WebSocket聊天室--支援多人同時線上及定時心跳檢測NettyWeb
- Golang 官方認可的 websocket 庫-gorilla/websocketGolangWeb
- WebSocket於HTTP 、WebSocket與Socket的區別WebHTTP
- Netty 的概述Netty
- (轉)WebSocket的原理Web
- netty系列之:netty中的Channel詳解Netty
- 學習WebSocket(一):Spring WebSocket的簡單使用WebSpring
- 【Netty】Netty傳輸Netty
- WebSocketWeb
- netty系列之:netty中的frame解碼器Netty
- netty系列之:netty對SOCKS協議的支援Netty協議
- netty系列之:netty中的ByteBuf詳解Netty
- 我的AI之路(26)--使用ROSBridge WebSocket和roslibjs構建一個簡單的控制機器人的web demoAIROSWebJS機器人
- 基於WebSocket的modbus通訊(三)- websocket和串列埠Web串列埠
- netty系列之:netty初探Netty
- 【Netty】Netty之ByteBufNetty
- Netty的wss支援Netty
- 聊聊netty的maxDirectMemoryNetty
- Netty的常用操作Netty
- WebSocket的調研分析Web
- Nginx 支援websocket的配置NginxWeb
- 老的Websocket介紹Web