对于不了解网络编程的开发人员来说,编写一个良好的服务端通讯程序是一件比较麻烦的事情.然而通过EC这个免费组件你可以非常简单地构建一个基于linux或win部署运行的网络服务程序.这种便利性完全得益于mono这些年来的不停发展.下面介绍通过EC这个组件如何通过短短十来分钟的时候内就能实现一个聊天室通讯服务程序.
在实现一个网络通讯程序的时候需要定义一个通讯协议,但EC已经集成了基础的协议功能,只需要根据交互的数据定义消息类型即可(EC提供两种序列化对象描述分别是protobuf和msgpack).
消息定义
针对简单的聊到室只需要定义登进,登出和发言这几个消息如下:
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
|
[MessageID(0x0001)]
[ProtoContract]
public
class
Login
{
[ProtoMember(1)]
public
string
Name {
get
;
set
; }
[ProtoMember(2)]
public
string
From {
get
;
set
; }
}
[MessageID(0x0003)]
[ProtoContract]
public
class
Signout
{
[ProtoMember(1)]
public
string
Name {
get
;
set
; }
[ProtoMember(2)]
public
string
From {
get
;
set
; }
}
[MessageID(0x0002)]
[ProtoContract]
public
class
Say
{
[ProtoMember(1)]
public
string
Content {
get
;
set
; }
[ProtoMember(3)]
public
string
From {
get
;
set
; }
[ProtoMember(2)]
public
string
Name {
get
;
set
; }
}
|
服务端
消息定义完成那用EC来制定一个聊天转发的服务端来说则是件非常简单的事情,只需要十来行代码就可以构建聊天和服务启动等相关功能.
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
|
[EC.Controller]
public
class
Program
{
static
void
Main(
string
[] args)
{
EC.ECServer.Open();
System.Threading.Thread.Sleep(-1);
}
public
void
OnLogin(EC.ISession session, Chat.Login e)
{
session.Channel.Name = e.Name;
e.From = session.Channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
session.Application.Server.GetOnlines())
{
if
(other != session.Channel)
session.Application.Server.Send(e, other);
}
}
public
void
OnSay(EC.ISession session, Chat.Say e)
{
e.Name = session.Channel.Name;
e.From = session.Channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
session.Application.Server.GetOnlines())
{
if
(other != session.Channel)
session.Application.Server.Send(e, other);
}
}
}
|
以上一个简单的聊取室的登进和聊天的功能,不过还有一个需要我们去处理的就是当用户断开后如果反映给其他用户.在EC中监控连接断开的过程需要通过一个AppModel来监控,发布有连接断开了则向其他连接发送登出信息,代码如下:
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
|
public
class
AppModel : EC.IAppModel
{
public
void
Init(EC.IApplication application)
{
application.Disconnected += (o, e) =>
{
Beetle.Express.IChannel channel = e.Session.Channel;
Chat.Signout msg =
new
Signout();
msg.Name = channel.Name;
msg.From = channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
application.Server.GetOnlines())
{
if
(other != channel)
application.Server.Send(msg, other);
}
};
}
public
string
Name
{
get
{
return
"AppModel"
; }
}
public
string
Command(
string
cmd)
{
throw
new
NotImplementedException();
}
}
|
EC提供一个IAppModel的自定义功能,通过AppModel可以监控用户会话,和处理全局消息的能力;在以后的文章再详细介绍.
客户端
EC同样提供便利的Client功能对象,你只需要定义简单的代码就可以向对应的服务端发送和接收相应的消息来处理.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
EC.ProtoClient mClient =
new
EC.ProtoClient(
"127.0.0.1"
);
mClient.Receive = (o, p) => {
if
(p.Message is Say)
{
Invoke(
new
Action<Say>(OnSay), p.Message);
}
else
if
(p.Message is Login)
{
Invoke(
new
Action<Login>(OnLogin), p.Message);
}
else
if
(p.Message is Signout)
{
Invoke(
new
Action<Signout>(OnSignout), p.Message);
}
};
mClient.Send(
new
Say{ Content=t
"你好"
});
|
借助于Xamarin我们还可以同样的方式把功能移植到不同平台下运行如android,ios等
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
|
private
IServiceChannel mClient =
new
ServiceChannel(
"10.0.2.2"
,10034);
protected
override
void
OnCreate (Bundle bundle)
{
base
.OnCreate (bundle);
ServiceChannel.Register (
typeof
(MainActivity).Assembly);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
EditText name = FindViewById<EditText> (Resource.Id.txtname);
EditText say = FindViewById<EditText> (Resource.Id.txtsay);
TextView content = FindViewById<TextView> (Resource.Id.txtContent);
mClient.Receive = (o, p) => {
content.Post(
delegate
{
content.Append(p.Message.ToString());
});
};
FindViewById<Button> (Resource.Id.btnlogin).Click +=
delegate
{
Login login =
new
Login();
login.Name = name.Text;
mClient.Send(login);
};
FindViewById<Button> (Resource.Id.btnsay).Click +=
delegate
{
Say s =
new
Say{ Content=say.Text};
mClient.Send(s);
};
// Get our button from the layout resource,
// and attach an event to it
}
|
这样一个多平台的基础聊天功能就完成了
个人站:www.ikende.com
个人开源项目github.com/IKende
elastic communication component for .net
对于不了解网络编程的开发人员来说,编写一个良好的服务端通讯程序是一件比较麻烦的事情.然而通过EC这个免费组件你可以非常简单地构建一个基于linux或win部署运行的网络服务程序.这种便利性完全得益于mono这些年来的不停发展.下面介绍通过EC这个组件如何通过短短十来分钟的时候内就能实现一个聊天室通讯服务程序.
在实现一个网络通讯程序的时候需要定义一个通讯协议,但EC已经集成了基础的协议功能,只需要根据交互的数据定义消息类型即可(EC提供两种序列化对象描述分别是protobuf和msgpack).
消息定义
针对简单的聊到室只需要定义登进,登出和发言这几个消息如下:
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
|
[MessageID(0x0001)]
[ProtoContract]
public
class
Login
{
[ProtoMember(1)]
public
string
Name {
get
;
set
; }
[ProtoMember(2)]
public
string
From {
get
;
set
; }
}
[MessageID(0x0003)]
[ProtoContract]
public
class
Signout
{
[ProtoMember(1)]
public
string
Name {
get
;
set
; }
[ProtoMember(2)]
public
string
From {
get
;
set
; }
}
[MessageID(0x0002)]
[ProtoContract]
public
class
Say
{
[ProtoMember(1)]
public
string
Content {
get
;
set
; }
[ProtoMember(3)]
public
string
From {
get
;
set
; }
[ProtoMember(2)]
public
string
Name {
get
;
set
; }
}
|
服务端
消息定义完成那用EC来制定一个聊天转发的服务端来说则是件非常简单的事情,只需要十来行代码就可以构建聊天和服务启动等相关功能.
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
|
[EC.Controller]
public
class
Program
{
static
void
Main(
string
[] args)
{
EC.ECServer.Open();
System.Threading.Thread.Sleep(-1);
}
public
void
OnLogin(EC.ISession session, Chat.Login e)
{
session.Channel.Name = e.Name;
e.From = session.Channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
session.Application.Server.GetOnlines())
{
if
(other != session.Channel)
session.Application.Server.Send(e, other);
}
}
public
void
OnSay(EC.ISession session, Chat.Say e)
{
e.Name = session.Channel.Name;
e.From = session.Channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
session.Application.Server.GetOnlines())
{
if
(other != session.Channel)
session.Application.Server.Send(e, other);
}
}
}
|
以上一个简单的聊取室的登进和聊天的功能,不过还有一个需要我们去处理的就是当用户断开后如果反映给其他用户.在EC中监控连接断开的过程需要通过一个AppModel来监控,发布有连接断开了则向其他连接发送登出信息,代码如下:
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
|
public
class
AppModel : EC.IAppModel
{
public
void
Init(EC.IApplication application)
{
application.Disconnected += (o, e) =>
{
Beetle.Express.IChannel channel = e.Session.Channel;
Chat.Signout msg =
new
Signout();
msg.Name = channel.Name;
msg.From = channel.EndPoint.ToString();
foreach
(Beetle.Express.IChannel other
in
application.Server.GetOnlines())
{
if
(other != channel)
application.Server.Send(msg, other);
}
};
}
public
string
Name
{
get
{
return
"AppModel"
; }
}
public
string
Command(
string
cmd)
{
throw
new
NotImplementedException();
}
}
|
EC提供一个IAppModel的自定义功能,通过AppModel可以监控用户会话,和处理全局消息的能力;在以后的文章再详细介绍.
客户端
EC同样提供便利的Client功能对象,你只需要定义简单的代码就可以向对应的服务端发送和接收相应的消息来处理.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
EC.ProtoClient mClient =
new
EC.ProtoClient(
"127.0.0.1"
);
mClient.Receive = (o, p) => {
if
(p.Message is Say)
{
Invoke(
new
Action<Say>(OnSay), p.Message);
}
else
if
(p.Message is Login)
{
Invoke(
new
Action<Login>(OnLogin), p.Message);
}
else
if
(p.Message is Signout)
{
Invoke(
new
Action<Signout>(OnSignout), p.Message);
}
};
mClient.Send(
new
Say{ Content=t
"你好"
});
|
借助于Xamarin我们还可以同样的方式把功能移植到不同平台下运行如android,ios等
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
|
private
IServiceChannel mClient =
new
ServiceChannel(
"10.0.2.2"
,10034);
protected
override
void
OnCreate (Bundle bundle)
{
base
.OnCreate (bundle);
ServiceChannel.Register (
typeof
(MainActivity).Assembly);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
EditText name = FindViewById<EditText> (Resource.Id.txtname);
EditText say = FindViewById<EditText> (Resource.Id.txtsay);
TextView content = FindViewById<TextView> (Resource.Id.txtContent);
mClient.Receive = (o, p) => {
content.Post(
delegate
{
content.Append(p.Message.ToString());
});
};
FindViewById<Button> (Resource.Id.btnlogin).Click +=
delegate
{
Login login =
new
Login();
login.Name = name.Text;
mClient.Send(login);
};
FindViewById<Button> (Resource.Id.btnsay).Click +=
delegate
{
Say s =
new
Say{ Content=say.Text};
mClient.Send(s);
};
// Get our button from the layout resource,
// and attach an event to it
}
|
这样一个多平台的基础聊天功能就完成了