<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      yunxizfj

      等待...

      導航

      測試Remoting服務端和客戶端的雙向通信

      最近有個項目,大致需求是,服務端發送消息通知客戶端上傳指定的數據,然后處理后一部分顯示在服務端界面上。也是在網上胡亂搜索一片,看到一篇Remoting廣播事件的博客+Remoting覺得這么還可以做。

      大致原理是:通過服務端廣播事件,客戶端通過調用遠程類將數據以參數的方式傳給服務端,然后激活服務端界面層的事件就達到雙向了。都是靠遠程類里的2個事件,一個給服務端,一個給客戶端,分別交叉執行。這就相當于: 服務端界面--遠程類--客戶端界面,遠程類起到了一個中間人的作用樣,是吧?

       

      先看看服務端封裝的Remoting的類

       

      public sealed class RemotingServer
          {
              HttpChannel tcpC;

              
      public static RemotingObject.Remoter Obj = null;

              
      static RemotingServer instance = new RemotingServer();

              
      public static RemotingServer GetRemotingServer
              {
                  
      get { return instance; }
              }

              RemotingServer()
              {
                  
      //tcpC = new TcpChannel(9000);
                  
              }

              
      public void ServerTakeOn()
              {
                  
      //if (!ExistServer(tcpC.ChannelName))
                  
      //{
                      RemotingConfiguration.RegisterWellKnownServiceType(typeof(RemotingObject.Remoter), "RemotingService", WellKnownObjectMode.Singleton);
                      BinaryServerFormatterSinkProvider serverProvider 
      = new BinaryServerFormatterSinkProvider();
                      BinaryClientFormatterSinkProvider clientProvider 
      = new BinaryClientFormatterSinkProvider();
                      serverProvider.TypeFilterLevel 
      = TypeFilterLevel.Full;
                      IDictionary props 
      = new Hashtable();
                      props[
      "port"= 9500;
                      tcpC 
      = new HttpChannel(props, clientProvider, serverProvider);
                      ChannelServices.RegisterChannel(tcpC);

                      Obj 
      = new RemotingObject.Remoter();
                      ObjRef objRef 
      = RemotingServices.Marshal(Obj, "RemotingMessage.soap");
                  
                  
      //}
              }

              
      public void ServerTakeOff()
              {
                  
      if (ExistServer(tcpC.ChannelName))
                  {
                      tcpC.StopListening(
      null);
                      ChannelServices.UnregisterChannel(tcpC);
                  }
              }

              
      private bool ExistServer(string serverName)
              {
                  
      bool tmp_b = false;
                  IChannel[] list 
      = ChannelServices.RegisteredChannels;
                  
      foreach (IChannel ic in list)
                  {
                      HttpChannel tmp_tcp 
      = (HttpChannel)ic;
                      
      if(tmp_tcp.ChannelName==serverName)
                      {
                          tmp_b 
      = true;
                          
      break;
                      }
                  }
                  
      return tmp_b;
              }
          }

       

      下面2句代碼特別的重要是服務端界面能和客戶端共同操作的遠程類

       

      Obj = new RemotingObject.Remoter();
      ObjRef objRef 
      = RemotingServices.Marshal(Obj, "RemotingMessage.soap");

       

      接下來看看客戶端的Remoting是怎么樣的

       

      public sealed class RemotingClient
          {

              HttpChannel tcp;

              IMessage imessage 
      = null;
              EventWrapper wrapper 
      = null;

              
      string _mes;

              
      public string ErrorMes
              {
                  
      get { return _mes; }
              }

              
      public IMessage GetObject1
              {
                  
      get { return imessage; }
              }
              
      public EventWrapper GetObject2
              {
                  
      get { return wrapper; }
              }

              
      static RemotingClient _client = new RemotingClient();
              
      public static RemotingClient GetObject
              {
                  
      get { return _client; }
              }
              RemotingClient()
              {
                  
              }

              
      public bool Connect(string serverIP)
              {
                  
      try
                  {

                      
      //_object = (RemotingObject.Remoter)Activator.GetObject(typeof(RemotingObject.Remoter),
                      
      //    string.Format("tcp://{0}:9000/RemotingService", serverIP));
                      
                      BinaryServerFormatterSinkProvider serverProvider 
      = new BinaryServerFormatterSinkProvider();
                      BinaryClientFormatterSinkProvider clientProvider 
      = new BinaryClientFormatterSinkProvider();
                      serverProvider.TypeFilterLevel 
      = TypeFilterLevel.Full;
                      IDictionary props 
      = new Hashtable();
                      props[
      "port"= 0;
                      tcp 
      = new HttpChannel(props, clientProvider, serverProvider);
                      ChannelServices.RegisterChannel(tcp);

                      
      //RemotingConfiguration.RegisterActivatedClientType(typeof(IMessage), string.Format("tcp://{0}:9000/RemotingService", serverIP));
                      imessage = (IMessage)Activator.GetObject(typeof(IMessage), string.Format("http://{0}:9500/RemotingMessage.soap", serverIP));
                      wrapper 
      = new EventWrapper();
                      
                      
      return true;
                  }
                  
      catch(Exception ex)
                  {
                      _mes 
      = ex.Message;
                      
      return false;
                  }
              }

              
      public void UnConnect()
              {
                  
      if (ExistServer(tcp.ChannelName))
                  {
                      ChannelServices.UnregisterChannel(tcp);
                  }
              }

              
      private bool ExistServer(string serverName)
              {
                  
      bool tmp_b = false;
                  IChannel[] list 
      = ChannelServices.RegisteredChannels;
                  
      foreach (IChannel ic in list)
                  {
                      HttpChannel tmp_tcp 
      = (HttpChannel)ic;
                      
      if (tmp_tcp.ChannelName == serverName)
                      {
                          tmp_b 
      = true;
                          
      break;
                      }
                  }
                  
      return tmp_b;
              }
          }

       

       

      是通過HTTP協議的,如果是域名的話,好像要先解析成IP吧?連接服務端,獲取遠程對象,給出屬性返回讓客戶端界面能操作遠程類

      接下來就是客戶端連接的代碼,連接成功后,取出遠程類,關聯遠程類的事件

       

             #region 連接
              
      private void btnConnect_Click(object sender, EventArgs e)
              {
                  
      if (!client.Connect(tbxIp.Text))
                  {
                      MesBox.Show(client.ErrorMes, 
      0);
                      
      return;
                  }
                  imessage 
      = client.GetObject1;
                  wrapper 
      = client.GetObject2;
                  
      try
                  {
                      wrapper.SendMessageEven 
      += new SendMessageEvenHandler(GetTxt);
                      imessage.SendMessageEven 
      += new SendMessageEvenHandler(wrapper.SendMessageing);
                  }
                  
      catch (Exception ex)
                  {
                      MesBox.Show(ex.Message, 
      0);
                      
      return;
                  }
                  btnConnect.Text 
      = "已連接";
                  btnConnect.Enabled 
      = false;
              }
              
      #endregion

       

       

             #region 服務端廣播
              
      private void GetTxt(string txt)
              {
                  
      if (txt == "A")
                  {
                      
      string ip = GetlocalIP();
                      List
      <string> tmp = GetHardInfo();
                      imessage.AddInfo(ip, tmp);
                  }
              }
              
      #endregion

       

       

      上面代碼中參數TXT==A,那是我自己胡弄的一個標識,不重要,然后獲取客戶端的IP和硬盤信息,通過調用AddInfo方法傳給服務端原程類。

      在遠程類中有事件處理的方法,在AddInfo方法內會調用,那么關聯服務端界面的方法就會被執行,數據也通過參數傳遞過去了

       

      public class Remoter : MarshalByRefObject, IMessage
          {

              
      #region IMessage 成員

              
      public event SendMessageEvenHandler SendMessageEven;

              
      public List<string> HardDeskInfo = new List<string>();

              
      public void SendMessage( string txt)
              {
                  
      if (SendMessageEven != null)
                  {
                      SendMessageEvenHandler tmp_even 
      = null;
                      
      foreach (Delegate dl in SendMessageEven.GetInvocationList())
                      {
                          
      try
                          {
                              tmp_even 
      = (SendMessageEvenHandler)dl;
                              tmp_even(txt);
                          }
                          
      catch
                          {
                              SendMessageEven 
      -= tmp_even;
                          }
                      }
                  }
              }
              
      public void AddInfo(string IP, List<string> hardinfo)
              {
                  
      string tmp = string.Empty;
                  
      foreach (string s in hardinfo)
                  {
                      
      //獲取剩余大小
                      string tmp1 = s.Substring(s.LastIndexOf("@"+ 1);
                      
      //獲取分區@總大小
                      string tmp2 = s.Substring(0, s.Length - tmp1.Length - 1);
                      
      //獲取總大小
                      string tmp3 = tmp2.Substring(tmp2.LastIndexOf("@"+ 1);
                      
      //獲取分區
                      string tmp4 = tmp2.Substring(0, tmp2.Length - tmp3.Length - 1);
                      
      //格式是 IP@分區@總大小@剩余大小
                      tmp = string.Format("{0}@{1}@{2}@{3}", IP, tmp4, tmp3, tmp1);
                      HardDeskInfo.Add(tmp);
                      ClientReciveData(tmp);
                  }
              }
              
      public void ClearInfo()
              {
                  HardDeskInfo.Clear();
              }
              
      public override object InitializeLifetimeService()
              {
                  
      return null;
              }
              
      #endregion

              
      #region 激活服務端事件
              
      public delegate void ClientReciveDataEvenHandler(string txt);
              
      public event ClientReciveDataEvenHandler ClientReciveDataEven;
              
      public void ClientReciveData(string txt)
              {
                  
      if (ClientReciveDataEven != null)
                  {
                      ClientReciveDataEvenHandler tmp_even 
      = null;
                      
      foreach (Delegate dl in ClientReciveDataEven.GetInvocationList())
                      {
                          
      try
                          {
                              tmp_even 
      = (ClientReciveDataEvenHandler)dl;
                              tmp_even(txt);
                          }
                          
      catch
                          {
                              ClientReciveDataEven 
      -= tmp_even;
                          }
                      }
                  }
              }
              
      #endregion

          }

       

       

      上面這個就是原創類了,是繼承于接口IMessage

       

      namespace RemotingObject.Common
      {
          
      public delegate void SendMessageEvenHandler(string txtt);

          
      public interface IMessage
          {
              
      event SendMessageEvenHandler SendMessageEven;
              
      void SendMessage(string txt);
              
      void AddInfo(string IP, List<string> hardinfo);
          }
      }

       

       

      接口和遠程類是不同的類庫生成的DLL,在服務端2個都會被調用,但是客戶端只會調用接口的DLL,中間還有一個事件適配器吧?是這么叫的吧?這個方式源于Remoting服務端事件廣播

       

      namespace RemotingObject.Common
      {
          
      public class EventWrapper : MarshalByRefObject
          {
              
      public event SendMessageEvenHandler SendMessageEven;

              
      public void SendMessageing( string txt)
              {
                  SendMessageEven(txt);
              }

              
      public override object InitializeLifetimeService()
              {
                  
      return null;
              }
          }
      }

       

       

      這2個的關系我到現在還沒搞懂的,不過能使用它們就很不錯啦

      最后看看服務端界面方法關聯的遠程類事件

       

             #region 窗體加載
              
      private void frmMain_Load(object sender, EventArgs e)
              {
                  _server 
      = RemotingServer.GetRemotingServer;
                  _server.ServerTakeOn();
                  RemotingServer.Obj.ClientReciveDataEven 
      += new RemotingObject.Remoter.ClientReciveDataEvenHandler(ClientReciveData);
              }
              
      #endregion

              
      #region 窗體關閉
              
      private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
              {
                  RemotingServer.Obj.ClientReciveDataEven 
      -= new RemotingObject.Remoter.ClientReciveDataEvenHandler(ClientReciveData);
                  _server.ServerTakeOff();
              }
              
      #endregion

              
      #region 遠程類事件
              
      private void ClientReciveData(string txt)
              {
                  SetLst(txt);
              }
              
      #endregion
             
      #region 設置列表
              
      private void SetLst(string tmp)
              {
                  
      string ip = string.Empty;
                  
      string dir = string.Empty;
                  
      string all = string.Empty;
                  
      string free = string.Empty;
                  
      //剩余大小
                  string tmp1 = tmp.Substring(tmp.LastIndexOf("@"+ 1);
                  
      //IP@分區@總大小
                  string tmp2 = tmp.Substring(0, tmp.Length - tmp1.Length - 1);
                  
      //總大小
                  string tmp3 = tmp2.Substring(tmp2.LastIndexOf("@"+ 1);
                  
      //IP@分區
                  string tmp4 = tmp2.Substring(0, tmp2.Length - tmp3.Length - 1);
                  
      //分區
                  string tmp5 = tmp4.Substring(tmp4.LastIndexOf("@"+ 1);
                  
      //IP
                  string tmp6 = tmp4.Substring(0, tmp4.Length - tmp5.Length - 1);

                  ip 
      = tmp6;
                  dir 
      = tmp5;
                  all 
      = tmp3;
                  free 
      = tmp1;

                  ListViewItem itm 
      = new ListViewItem();
                  itm.SubItems[
      0].Text = ip;
                  itm.SubItems.Add(dir);
                  itm.SubItems.Add(all);
                  itm.SubItems.Add(free);

                  lst.Items.Add(itm);
              }

       

      接受到參數傳遞的數據,處理下放到ListView顯示出來,不過我記得Remoting遠程類所激活的事件都應該是子線程的吧?怎么我這沒報錯(子線程不能操作主線程的控件)呢?

      整個工程大概就是這樣的,希望上面的思路不是很亂吧?

      posted on 2010-03-17 17:25  yunxizfj  閱讀(2693)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 国内少妇人妻偷人精品视频| 亚洲精品一区二区三区不| 国产精品久久久一区二区三区 | 国产欧美日韩精品丝袜高跟鞋| 欧美巨大极度另类| AV极品无码专区亚洲AV| 五月天免费中文字幕av| 精品国产午夜福利在线观看| 在线观看潮喷失禁大喷水无码| 亚洲成a人v欧美综合天堂下载| 亚洲av第一区二区三区| 国产精品不卡区一区二| 日本亚洲中文字幕不卡| 日韩三级一区二区在线看| 亚洲产在线精品亚洲第一站一| 国产大尺度一区二区视频| 榕江县| 国产熟女精品一区二区三区| 精品中文字幕人妻一二| 在线a亚洲老鸭窝天堂| 亚洲在战av极品无码| 国产免费AV片在线看| 亚洲aⅴ男人的天堂在线观看| 欧美无人区码suv| 国产成人不卡一区二区| free性开放小少妇| 一区二区和激情视频| 虎白女粉嫩尤物福利视频| 国产网红主播精品一区| 日韩精品不卡一区二区三区| 国产色无码专区在线观看| 午夜自产精品一区二区三区| 国产精品国语对白一区二区| 波多野结衣久久一区二区| 风流老熟女一区二区三区| 69人妻精品中文字幕| 少妇办公室好紧好爽再浪一点| 精品人妻伦一二二区久久| 国产精品一区在线蜜臀| 亚洲真人无码永久在线| 欧洲美熟女乱又伦免费视频|