怎么写个socket与netty通信

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么写个socket与netty通信相关的知识,希望对你有一定的参考价值。

参考技术A netty v3.9.4
websocket连接建立前,客户端需要与服务器进行握手(http协议) 确认websocket连接,也就是说在处理websocket请求前,必需要处理一些http请求。
websocket到现在为止,已经有多个版本,netty有相应的对应类,这部分处理一般不需要人工干预。

如果运行正常的话,会在页面的文本框中显示1-20记数。
可以通过firefox或chrome的开发人员工具,显看浏览器与服务器的交互。

主要是HttpServerChannelHandler2,加了些注释和少量debug代码。
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

package org.sl.demo.httpserver1;

import java.util.List;
import java.util.Map;

import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpHeaders;
import org.jboss.netty.handler.codec.http.HttpMethod;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketFrame;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import org.jboss.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;

public class HttpServerChannelHandler2 extends SimpleChannelHandler
public static boolean debug = true;

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e)
Channel ch = e.getChannel();
Object msg = e.getMessage();

if(debug)
System.out.println("---------------");
System.out.println("message: "+msg.getClass());

//虽然是websocket,但在建立websocket连接前,先进行http握手,所以,这时也要处理http请求
//在http握手完成后,才是websocket下的通信
if(msg instanceof HttpRequest)
processHttpRequest(ch, (HttpRequest)msg);
else if(msg instanceof WebSocketFrame)
processWebsocketRequest(ch,(WebSocketFrame)msg);
else
//未处理的请求类型



//这个方法:
//1.完成websocket前的http握手
//2.屏蔽掉非websocket握手请求
void processHttpRequest(Channel channel,HttpRequest request)
HttpHeaders headers = request.headers();
if(debug)
List<Map.Entry<String,String>> ls = headers.entries();
for(Map.Entry<String,String> i: ls)
System.out.println("header "+i.getKey()+":"+i.getValue());



//屏蔽掉非websocket握手请求
//只接受http GET和headers['Upgrade']为'websocket'的http请求
if(!HttpMethod.GET.equals(request.getMethod())
|| !"websocket".equalsIgnoreCase(headers.get("Upgrade")))
DefaultHttpResponse resp = new DefaultHttpResponse(
HttpVersion.HTTP_1_1,
HttpResponseStatus.BAD_REQUEST);
channel.write(resp);
channel.close();
return;


WebSocketServerHandshakerFactory wsShakerFactory = new WebSocketServerHandshakerFactory(
"ws://"+request.headers().get(HttpHeaders.Names.HOST),
null,false );
WebSocketServerHandshaker wsShakerHandler = wsShakerFactory.newHandshaker(request);
if(null==wsShakerHandler)
//无法处理的websocket版本
wsShakerFactory.sendUnsupportedWebSocketVersionResponse(channel);
else
//向客户端发送websocket握手,完成握手
//客户端收到的状态是101 sitching protocol
wsShakerHandler.handshake(channel, request);



//websocket通信
void processWebsocketRequest(Channel channel, WebSocketFrame request)
if(request instanceof CloseWebSocketFrame)
channel.close();
else if(request instanceof PingWebSocketFrame)
channel.write(new PongWebSocketFrame(request.getBinaryData()));
else if(request instanceof TextWebSocketFrame)
//这个地方 可以根据需求,加上一些业务逻辑
TextWebSocketFrame txtReq = (TextWebSocketFrame) request;
if(debug) System.out.println("txtReq:"+txtReq.getText());

//向ws客户端发送多个响应
for(int i=1; i<=20; i++)
channel.write(new TextWebSocketFrame(""+i));
tryThread.sleep(300);catch(Exception ex)

else
//WebSocketFrame还有一些




其他类跟网上的差不多: http://blog.csdn.net/shagoo/article/details/8028813
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

package org.sl.demo.httpserver1;

import java.net.InetSocketAddress;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.socket.nio.NioserverSocketChannelFactory;

public class HttpServer implements Runnable
int port = 80;

public HttpServer(int port)
this.port = port;


@Override
public void run()
ServerBootstrap b = new ServerBootstrap(
new NioServerSocketChannelFactory(
Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));
b.setPipelineFactory(new HttpServerChannelPipelineFactory());
b.setOption("child.tcpNoDelay", true);
b.setOption("child.keepAlive", true);
b.bind(new InetSocketAddress(port));


public static void main(String[] args)
new HttpServer(80).run();



?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

package org.sl.demo.httpserver1;

import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
import org.jboss.netty.handler.codec.http.websocketx.WebSocket00FrameDecoder;
import org.jboss.netty.handler.codec.http.websocketx.WebSocket08FrameDecoder;

public class HttpServerChannelPipelineFactory implements ChannelPipelineFactory

@Override
public ChannelPipeline getPipeline() throws Exception
ChannelPipeline cp = Channels.pipeline();

cp.addLast("decoder", new HttpRequestDecoder());
// cp.addLast("decoder", new WebSocket00FrameDecoder());
cp.addLast("encoder", new HttpResponseEncoder());
// cp.addLast("downhandler", new HttpServerDownstreamHandler());
// cp.addLast("uphandler", new HttpServerUpstreamHandler());
cp.addLast("handler", new HttpServerChannelHandler2());

return cp;




测试页面:
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67

<html>
<head>
<script >
function connect1()
alert('connect1');

var ta = document.getElementById('responseText');
var socket = new WebSocket('ws://127.0.0.1/websocket');
if (window.WebSocket)

else
alert('Your browser does not support Web Socket.');
return;

socket.onopen = function(event)
ta.value = "Web Socket opened!";


socket.onmessage = function(event)
ta.value = event.data;
;

socket.onclose = function(event)
ta.value = "Web Socket closed";
;


function connect()
alert('connect');
var socket;
if (!window.WebSocket)
window.WebSocket = window.MozWebSocket;


if (window.WebSocket)
socket = new WebSocket("ws://127.0.0.1/websocket");
socket.onmessage = function(event)
var ta = document.getElementById('responseText');
ta.value = event.data;
;

socket.onopen = function(event)
var ta = document.getElementById('responseText');
ta.value = "Web Socket opened!";
socket.send('hello');
;

socket.onclose = function(event)
var ta = document.getElementById('responseText');
ta.value = "Web Socket closed";
;

socket.onerror = function(event)
;
else
alert("Your browser does not support Web Socket.");


</script>
</head>

<body>
<input type="button" onclick="connect1()" value="ws connect1"/> <br/><br/>
<input type="button" onclick="connect()" value="ws connect"/> <br/><br/>
<input id="responseText" type="text" value="123456"/>
</body>
</html>本回答被提问者和网友采纳

基于Netty实现一套分布式IM系统

计算机编程的学习,能不能把知识学到手,讲究的是动手实践。在我编写的文章中,基本都是以实践代码验证结果为核心来讲述文章内容。

从小我就喜欢动手,就以一个即时通信的项目为例,已经基于不同技术方案实现了5、6次,仅仅为了实践技术

正如上图这样:

  • 1)有些是刚学完Socket和Swing的时候,想动手试试这些技术能不能写个QQ出来;
  • 2)也有的是因为实习培训需要完成的项目,不过在有了一些基础后,一周时间就能写完全部功能;
  • 3)虽然这些项目在现在看上去还是丑丑的界面,以及代码逻辑可能也不是那么完善。但放在学习阶段的每一次实现中,都能为自己带来很多技术上的成长。

那么,这次借本文的机会,将IM实践的机会留给你,希望你能用的上。

接下来的内容,我会为你介绍如何开发一个IM的方方面面,包括系统架构、通信协议、单聊群聊、表情发送、UI事件驱动等,以及全套的实践源码让你可以上手学习。

http://www.blogjava.net/paulwong/

http://www.blogjava.net/paulwong/MyPosts.html

http://www.blogjava.net/paulwong/MyPosts.html?page=2

http://www.blogjava.net/paulwong/MyPosts.html?page=3

http://www.blogjava.net/paulwong/MyPosts.html?page=6

http://www.blogjava.net/BlogList.aspx

http://www.blogjava.net/TopPosts.aspx

以上是关于怎么写个socket与netty通信的主要内容,如果未能解决你的问题,请参考以下文章

手写RPC框架第二章《netty通信》

netty,websocket,ipc(lpc和rpc),Nio之间的相互调用

netty基本使用- socket通信

高性能底层怎么运作?一文帮你吃透Netty架构原理

谁能用C语言写个最简单socket通信服务端和客户端示例

Netty,网络通信的权威专家