百度过,不过感觉不能快速上手,需求:移动平台请求数据(crud都有),求一个DEMO,当然描述一下也行,用socket实现,不用webservice,我也说一下我的疑点吧,其实我也就看了一晚上,server端和client端直接和socket交互的是那一层?他们具体的职能是什么大神们最好能给我个代码的框架,只有接口即可,实现可以不要,例如client实现一个最简单的crud。
好吧,我说一下我认为的逻辑(一直做bs开发,理解的不对请无视):UI→Controller(client端)→socket共通类(arg1:指令类型,arg2[]:参数列表)→Socket通信→Controller?(server端)[→BLL(Action,不知道有没有这一层)]→DAL(service)→DB Server
BLL(Action)这一层是不是 应该放在client对请求的数据进行编辑用的?我想知道socket通信实现方法应该在client和server的哪一层来调用?

解决方案 »

  1.   

    socket很复杂的,不是一两句话可以说清楚,crud逻辑太复杂,你用socket去实现,会很痛苦,最好用webservice,如果不行,用rpc也行,
      

  2.   

    如果你一定要用socket去做,建议你学webservice,用socket传递xml文本,client向server发出的各种命令,都用xml表示,server向client返回任何结果也都用xml文本表示,这样你就可以把socket通讯独立出来,作为一个孤立的组建和业务逻辑层和数据层都无关,
      

  3.   

    所谓套接字,很多人说的只是指Windows Socket API以及在此之上封装的库函数(比如.net TCPClient UDPClient,mfc的CSocket,Delphi的Indy).
      

  4.   

    不过如果要这样做,还不如用http协议做,用http传输xml文件更为简单,如果用http协议,就和用webservice没多少差别,呵呵,不管用什么方式,socket也好,http也好,只要你用xml文件做请求和应答,那么你可以决定在任何一个层次上做网络通讯,你可以把业务逻辑层放在服务器,然后client用xml调用服务器上的业务逻辑层,client只做界面,也可以把业务逻辑层放在client,用xml去调用服务器上的数据库,但如果你用client直接访问数据层,那还不如就直接用ado.net直接从客户端访问数据库服务器,这也是最普通的cs结构程序的做法,也是最容易实现的做法,
      

  5.   

    用socket不用webservice主要是考虑到性能的问题,client肯定是不会直接访问服务器的,因为手机平台塞班、安卓、WP、IOS要公用这一个server。
      

  6.   


    你需要传输大量数据吗?如果不需要用webservice性能不差,如果共用server,那么最好用http协议传输xml指令的方式实现,因为各种系统对http协议支持都比较好,不过这样做会很辛苦,即使是用http协议,也会比直接用socket要容易得多,服务器你可以用java的servlet实现,或者用asp.net也可以,服务器要容易得多,客户端就麻烦,
      

  7.   

    数据量挺小的吧,类似手机人人网客户端,企业级开发也会用webservice么,那么你觉得手机人人网服务器是什么形式的。
      

  8.   

    以下或许是相当重要的入门知识,以免你以后对于通讯程序设计望洋兴叹。知识层之一:
    首先先要理解最基本的命令模式:    public interface ICommand
        {
            object parameter { get; set; }
            object Execute();
        }    public abstract class Command<T, S> : ICommand
        {
            public abstract S Execute(T parameter);        public object Execute()
            {
                return Execute((T)parameter);
            }        public object parameter{get;set;}
        }
    这就是服务器端处理命令网关的基础。假设我们写个简单的BLL服务    public class Hello : Command<string, string>
        {
            public override string Execute(string parameter)
            {
                return "hello, " + parameter + "!";
            }
        }
    然后写个简单的本地测试:            var cmd = new Hello();
                cmd.parameter="baby";
                var result = cmd.Execute();你可以看到,这个封装为独立对象的BLL命令被执行了,并且返回了期望的值。
    知识层之二:
    实际上你的服务器端可能有多达十几个工程,每一个都实现了数量不等的ICommand。而你的服务器架构当然是预先开发的,它不知道将来会有哪些BLL需要经过它来进行解析。也就是说服务器都能够提接口一致的BLL服务给客户端,而你可能需要首先使用MEF技术或者就是原始的反射技术来将所有的ICommand收集起来备用。例如这里我随便写一个demo,它反射当前应用程序启动域中的所有程序    private static Dictionary<string, Type> _commands = null;    public static Dictionary<string, Type> Commands
        {
            get
            {
                if (_commands == null)
                {
                    _commands = AppDomain.CurrentDomain
                        .GetAssemblies()
                        .SelectMany(asm => asm.GetTypes())
                        .Where(type => typeof(ICommand).IsAssignableFrom(type))
                        .Where(type => type.IsClass && !type.IsAbstract)
                        .ToDictionary(x => x.FullName, x => x);
                }
                return Program._commands;
            }
        }测试一下你能得到什么结果?你会看到你的程序可以将以 ConsoleApplication1.Hello 为键,在词典中收集了它所对应的ICommand实际实现类型Hello类型。这就是BLL扩展的基础。
    知识层之三:
    我们可以使用间接反射的方法从一个json字符串中得到一个Hello测试实例,然后计算结果,并且也输出为一个json字符串。例如(这里需要引用json.net类库)var commandType = "ConsoleApplication1.Hello";
    var input="{\"parameter\":\"baby\"}";
    var cmd = JsonConvert.DeserializeObject(input, Commands[commandType]) as ICommand ;
    var result = cmd.Execute();
    var output = JsonConvert.SerializeObject(result);执行它,你可以看到output里边已经准备好了返回给客户端的json字符串了。知识层之四:
    客户端可以随便定义一个class以便轻松地使用json.net产生这个json字符串。例如namespace ConsoleApplication1
    {
        public class Hello
        {
            public string parameter;
        }.....你可以看到,我这里使用了field而不是property。这完全没有关系!客户端对Hello命令的定义完全不必跟服务器端完全一致,甚至客户端多一些属性、少一些属性也无所谓,因为json都可以将其反序列化为服务器端的Hello命令。知识层之五:
    要有一个基本的信令设计。例如我们用  类型|json 这样的简单格式表达客户端的消息内容,那么就是客户端要通过socket发送给服务器这样的字符串:
        
         ConsoleApplication1.Hello|{\"parameter\":\"baby\"}而服务器在将竖线“|”之前的内容解析为commandType ,再将竖线之后的内容(直到换行或者回车符号之前的内容)解析为input,于是它就能计算出output,返回给客户端了!此时客户端自然知道用什么类型将返回的json字符串反序列出来。
    以上是最基本的一种通讯机制demo。只有第一个命令模式有点技术含量,剩下的都是知识经验问题,而没有多么的技术。如果你深入理解和熟练使用这个简单的demo,就不会对设计复杂的命令通讯程序有什么疑惑,不至于只会拖拉鼠标来使用wcf而不敢自己来设计更加专业(以及比WCF要高效和方便很多)的通讯程序了!!
      

  9.   

    上面    ConsoleApplication1.Hello|{\"parameter\":\"baby\"}应该写为    ConsoleApplication1.Hello|{"parameter":"baby"}这是socket消息传送内容,因此没有反斜杠。并且我会默认地在客户端和服务器端使用UTF8编码方式。
      

  10.   

    我喜欢直接用ASP.Net HTTP Handler,轻量,我往.ashx这样的一个地址POST一个request class的json字符串,再接收一个response class的json序列化后的字符串,再反序列化得到response的内容。其实这就是个轻量级的service。
      

  11.   

    使用socket,特别是使用长连接异步处理,你会发现要比http通讯快许多倍,特别是输入参数和返回对象是比较复杂的自定义类型时。比WCF快多少倍我都懒的去比较了。当然长连接异步异步处理在最基本的信令设计上要稍微复杂一点。简单说一下长连接:
    例如这样的格式(序列号为ulong类型):
      
          命令类型|发送端会话id|接收端会话id|序列号|json这样当服务器端刚刚解析到“接收端会话id”不是自己时,就简单地发消息发送给对应的客户端就行了。而当消息确实是发送给自己的,它异步地执行json,然后将返回结果以格式
            返回数据类型|服务器端id|客户端id|-序列号|json的格式返回。比如说客户端与服务器端建立了连接之后,它可能按照次序1、2、3、4、5的次序发送了5命令,然后异步地以3、5、2、1、4的次序收到了返回结果(因为服务器端是异步执行这些命令的,这些命令所用时间长短不同,所以返回的次序不定),那么客户端需要一个异步机制,在收到命令返回时才去回调相应的命令的下一步处理程序。
      

  12.   

    实际上这里的parameter的类型,你可以看作是常说的所谓“model”。而ICommand(的实际的子类)本身,你可以看作常说的所谓“BLL”。客户端只需要有最简单最低级的、关于model和BLL类型的代理类型,例如这里的Hello就是一个BLL服务。通讯的目的如是为了实现什么crud,那么层次也太低了。谁也不敢真正把crud随便暴露在网络上让客户端随便修改删除你的数据吧!通讯的目的,就好象比如说我们通过网络下订单,通过它给火星上的异性发个情书,总之真正的信令内容越是贴近业务才越真正能够体现强大的服务端实用性、体现出可以将少数api激发出千变万化的前端交互界面程序。而不是什么数据库“增删改查”那种东西。因此才有了BLL设计。去分析和设计BLL,要深入业务,而不是什么数据库增删改查。
      

  13.   

    "server端和client端直接和socket交互的是那一层?他们具体的职能是什么大神们最好能给我个代码的框架,只有接口即可,实现可以不要,例如client实现一个最简单的crud。"1,server端和client端直接和socket交互的是那一层:通信层,一般有流和文本两种通信函数接口。2,代码:http://download.csdn.net/detail/zhangxuyu1118/260015
    3、client实现crud,你要根据需要自己设计协议,比如:收到 "ADD 1 ZXYU " 你就做新增 1 ZXYU的 操作。
      

  14.   

    sp老大,顺便问一下,凭你之前做过的socket项目,如果用socket来通信的话,各种指令,传递的业务数据是不是都需要按照自己的需求去序列化?
    这个序列化是自己去制定规约还是有现成的框架呀?
      

  15.   

    首先非常感谢大神的回复,顺便也让我学会了如何使用命令模式,我还有一点疑问,命令模式是把一个请求封装为一个对象,也就是说这个BLL服务不同于以往的三层,是不是只要是不同的请求就要定义一个类,因为只能有一个execute方法?以往的三层中,基本上是一个DAL对应一个BLL(是以模块划分的),而命令模式中的BLL是以动作(请求)划分的?