Ma client server简明教程

翻译:ShiningRay @ NirvanaStudio
原文地址:http://minnow.cc.gatech.edu/squeak/2978

{译者:Ma client server是针对Smalltalk的一个网络应用框架,由于十分好用,介绍到这里来}

简介

Ma client server 可以帮助你非常方便地书写客户端/服务器端(Client/Server,以下简称C/S)程序。事实上,它容易到了服务器段程序只要用一行代码:

MaServerSocket new listenOn: 12345 answer: [ :requestByteArray | 'Hello world!' asByteArray ]

这个框架实际上是基于一个稳定可靠的、多线程的Socket模型,是由John McIntosh分享给我的。

在C/S模型中,一个客户端向服务器段发送一个请求,然后服务器处理请求并返回一个应答。

这个框架提供了相互配合的两层结构。你选择其中你想使用的一层然后写两个程序。一个客户端程序会给远程服务器发送请求,服务器上则运行着另一个程序处理请求。

如果你选择较低的一层,“套接字层”(Socket Layer),你发送的是ByteArray(字节数组,一个基本类)的请求,接收的是ByteArray的应答。在较高一层,“对象请求层”(Object Rquest Layer),你可以发送任意的请求对象,获取任意的对象作为应答。较高层上使用了“Ma对象序列化”(Ma Object Serialization)框架来将对象转换成ByteArray,然后让较低的一层为你把这个ByteArray发送出去。

使用套接字层

建立服务器

如果你只是要发送和接收ByteArray的数据,你可以随便写你的服务器程序。但记住,不管在哪里,你要接收ByteArray作为输入,你就必须应答一个ByteArray

然后,要启动服务器:

myServerSocket _ MaServerSocket new
listenOn: 12345
answer:
[ :requestByteArray |
... 将 requestByteArray 传给你的服务器端程序 ... ]

MaServerSocket 利用了 SharedQueue和后台进程来确保处理过程不会因在网络上发送和接收ByteArray数据而阻塞,现在发送和接收完全在后台进行。“answer”块一次对一个客户端请求进行执行。

当你完成之后,一定要关闭套接字这样资源才能正确被释放:

myServerSocket shutdown

在客户端获得应答

下面客户端程序建立了一个MaClientSocket对象,要将IP地址作为ByteArray中的数字指明:

mySocket _ MaClientSocket hostAddress: #(192 168 1 1) asByteArray port: 12345.

建立了套接字之后还没有进行任何连接。只有在你发送请求的时候才会发生:

responseByteArray _ mySocket sendData: myRequestByteArray

同时具有一个sendData:startingAt:count:waitForReplyIn:方法可以达到最大的效率。如果你提供作为返回的ByteArray 不够大,你就会得到一个更大的。

可选的套接字事件

MaServerSocket 要用到一个 “server”, 默认是一个MaServer对象不过它什么也不做。但如果你给MaServer派生子类并且重写其中一些方法,这些方法会在如下时候调用套接字加入队列、一个ByteArray请求完全抵达,或者是发送一个响应等等。详细信息见MaServer

使用对象请求层

如果你选择使用对象请求层,你发送“请求”对象并获得某种应答对象。这样你可以专心写客户端和服务器程序,而不用关系如何解析ByteArray了。

建立服务器

这里当你准备开始写你的服务器段程序时,不是建立一个MaServerSocket对象,而是建立一个MaTcpRequestServer对象:

myServer _ MaTcpRequestServer protocol:
{ MyRequestClass1.
MyRequestClass2.
MyResponseClass1.
MyResponseClass2.
OrderedCollection.
Dictionary. "etc." }.

这是什么?是的,你必须告诉她你要发送和接收的所有类,来记录你请求对象的形式。例如,如果你有一个 SubmitArticleRequest类,里面有一个Article对象,你不仅要列出SubmitAritcleRequest类,还要给出Article和所有其他Article引用的类和这些类他们引用的类,如此继续。然而,你不需要给出String, ByteArray, Set, Symbol, SmallInteger, Float, True, False或者UndefinedObject等类。这些类已经自动成为协议的一部分了。

也可以指明一个MaServerConsole来接收事件。派生MaServerConole并改写他的一个通知方法,象下面这样,他就会被自动调用。

myServer _ console: myConsole

当你准备启动服务器时,你要使用 processOn:do:

myServer
processOn: 12345 ;
using:
[ :requestObject |
... 将 requestObject 传递给服务器程序,可以应答响应 ... ]

当完成之后,你需要关闭并释放系统资源:

myServer shutdown

建立客户端

你的客户端程序建立一个 MaTcpRequestServerLink 并指向服务器所监听的地址 hostAddress 和端口 port

myLinkToServer _ MaTcpRequestServerLink hostAddress: #(192 168 1 1) asByteArray port: 12345

在你要做任何事之前,你必须先建立连接。这确保你在客户端的镜像中包含了所有必须的协议 (如果没有就会抛出异常)。

myLinkToServer connect

如果要在网络状况和你的耐性做出平衡,你可能想改写默认的超时期限为30秒:

myLinkToServer timeoutSeconds: 30

在客户端获得应答

现在你已经连上了,你的客户端程序可以如下从服务器端获得应答:

myLinkToServer submit: someRequestObject

记住, someRequestObject 必须是协议的成员之一,同样你从submit:取回的应答对象也必须是协议之一:

好了!当你完成之后,别忘了断开连接这样你可以将网络资源还给系统

myLinkToServer disconnect

发表评论

电子邮件地址不会被公开。 必填项已用*标注