在忍无可忍的情况下,我终于抛弃了remoting

来源:互联网 发布:java怎么写爬虫 编辑:程序博客网 时间:2024/04/29 02:42

remoting最讨厌的就是有个绑定ip问题,如果绑定ip,那么只能绑定一个,那么如果机器是多网卡,则只能用绑定的这个ip访问。

这位说了可以绑定机器名啊。

绑定机器名的话,如果服务器是内网的就不行了。

 

举个例子吧,如果一个服务器是内网,如果绑定路由器的外网ip,并在路由器做映射,那么外网是可以通过外网ip访问,而且路由器映射端口必须和remoting的端口一样才行,但这样的话局域网内通过内网ip就连不上了。

如果绑定机器名,内网通过机器名可以,外网就不行了,即使在路由器上映射端口也不行,可以通过sniffer软件看到,外网可以连接上remoting的服务器,但是却不能用。

原因就在于remoting在开始的连接头就有个ip的验证,你可以看到外网客户发送的remoting连接头有比如202.102.128.68:6666这样的,而返回的信息中包含192.168.0.8:6666这样的,就是这样虽然能连接但是对不上号。

remoting坑爹就坑爹在这里,他对于连接的验证放在这种坑爹的地方。

 

据说有种办法可以改变什么传输链的,可以改变这remoting的连接头,但是我觉得没必要了,为什么呢,因为我本来用remoting就是为了方便,可以不用自己去处理tcp连接了,还有个远程对象可以用,但现在反而比自己处理tcp连接还麻烦了。于是我决定毅然抛弃remoting,用tcpclient自己搞定。

本以为很麻烦的,结果却没有那么麻烦,远程对象嘛,自己反射就行了,效果是一样的。就是多加了一个序列化反序列化的过程。

就是tcp部分,就是麻烦一点,得很仔细的处理,主要是如何协商和处理异常,因为一个不小心,服务器的程序就崩溃了,所以主要就是协商和异常处理,要让程序很皮实才行,不能动不动就崩溃,也不能造成内存只升不降,也不能造成莫名其妙的100%cpu占用,这就是remoting的好处,tcp协商,异常处理m$都给做好了,你怎么搞服务器程序都不会崩溃,很皮实很皮实的,自己搞一点考虑不周就崩溃。

当搞定了tcp的协商和异常处理后,发现了反射加载了dll却不释放的问题,最后用appdomain,appdomain是个好东西呀,他不光是可以加载和卸载dll,而且,dll一点进了appdomain,那么就没有崩溃这一说了,这样的话dll怎么搞都无所谓了,顶多会返回一个“调用的目标发生异常“的信息,而不像普通程序那样,一点异常没处理,整个程序就崩溃。

最后给通信加入了rsa+aes的加密,这样,remoting的优势荡然无存。

 

最后效果是这样的,服务器程序是一个windows服务,他里面是空的,基本就是一个tcplistener+反射的一个执行器,客户端连接服务器,通信过程用rsa+aes加密,然后客户端传输一个byte[],这个byte[]是一个dll,然后服务器开一个appdomain,里面assembly直接load这个byte[],连.dll文件都不会有,全在内存中,客户端发送指令,然后appdomain中直接inoke,结果返回给客户端。当客户端结束通信后,服务器就appdomain.unload释放掉。

 

这样以来,服务器端就是一个执行器,通用的,他几乎不用再去改变什么,也就无需去升级,无论想具体执行什么样的功能,全在客户端的dll中改就可以了,无论dll中具体方法怎么改怎么加,反正方法名都作为字符串传过去,无论dll中的方法有什么样的参数和数量,都是object[]的数组,无论返回值是什么玩意,都是object,都不用管,序列化成byte[]传回来处理就行了。这样服务器就以不变应万变了。如果没有反射的话,服务器就得写死了,每改动一点服务器程序都得重新编译和安装了。

 

最近老是遇到内存释放问题,说.net不用管释放完全就是一句屁话,很明显的,比如不用appdomain,那么程序运行8兆左右,一个客户连进来,30几兆,但是客户走了还是30几兆,又一个客户进来,50几兆,走了还50几兆,如此80几兆100几兆,不降了,即使开个线程定时gc.collect()也没用,还是不降。这样一会就不能用了。但是用了appdomain后,客户来了多,走了程序能基本稳定在30来兆左右,虽然还是会每次都增加一点,但是就可以接受了,再配合一个定制gc.collect()的线程,就可以用了。

原创粉丝点击