先來三個參考網站
1:介紹所需要的類別 跟Web的sample code 
https://msdn.microsoft.com/zh-tw/library/dn535720.aspx?f=255&MSPPError=-2147217396
2. signalr的邏輯跟ajaxhttp需求的差異
https://blogs.msdn.microsoft.com/msdntaiwan/2013/09/09/signalr-web-web/
3.Hub上的觀念使用
http://blog.darkthread.net/post-2012-07-10-signalr-remote-controller.aspx

這東西的邏輯很特別
好像起來以後用戶跟SERVER之間開一條獨立連線一樣
會有一個專有的context.connectId 在設定的對應好的hub上產生相對應的呼叫

像在用戶端要呼叫server端的function
server端也要寫用戶端可以互相對應的function
是完全委派的方法 

Server端
 

public partial class WinFormsServer : Form
   {
       public static int i = 0;
      
       private IDisposable SignalR { getset; }
       const string ServerURI = "http://localhost:8080";
       internal WinFormsServer()
       {
           InitializeComponent();
           EventArgs e=new EventArgs();
           ButtonStart_Click(sender,null);
       }
 
       private void ButtonStart_Click(object senderEventArgs e)
       {
           WriteToConsole("Starting server...");
           ButtonStart.Enabled = false;
           Task.Run(() => StartServer());
       }
 
       private void ButtonStop_Click(object senderEventArgs e)
       {
           Close();
       }
 
       private void StartServer()
       {
           try
           {
               SignalR = WebApp.Start(ServerURI);
           }
           catch (TargetInvocationException)
           {
               WriteToConsole("Server failed to start. A server is already running on " + ServerURI);
               this.Invoke((Action)(() => ButtonStart.Enabled = true));
               return;
           }
           this.Invoke((Action)(() => ButtonStop.Enabled = true));
           WriteToConsole("Server started at " + ServerURI);
       }
       internal void WriteToConsole(String message)
       {
           if (RichTextBoxConsole.InvokeRequired)
           {
               this.Invoke((Action)(() =>
                   WriteToConsole(message)
               ));
               return;
           }
           RichTextBoxConsole.AppendText(message + Environment.NewLine);
       }
 
       private void WinFormsServer_FormClosing(object senderFormClosingEventArgs e)
       {
           if (SignalR != null)
           {
               SignalR.Dispose();
           }
       }
   }
   class Startup
   {
       public void Configuration(IAppBuilder app)
       {
           app.UseCors(CorsOptions.AllowAll);
           app.MapSignalR();
       }
   }
   public class UserInfo
   {
       public string ContextID { getset; }
       public string Name { getset; }
 
   }
   public class MyHub : Hub
   {
       private void GetUserList()
       {
 
           var itme = from a in UserList
                      select new { a.Namea.ContextID };
           string jsondata = JsonConvert.SerializeObject(itme.ToList());
           Clients.All.getUserlist(jsondata);
 
       }
       public void Send(string namestring message)
       {
          
           var user = UserList.Where(u => u.Name == name).FirstOrDefault();
           var userSend = UserList.Where(u => u.ContextID == Context.ConnectionId).FirstOrDefault();
 
           Clients.Client(user.ContextID).addMessage(" User:" + userSend.Name + ":" + message + "  " + DateTime.Now,
               " User:" + userSend.Name
               + "  Id:"+ Context.ConnectionId);
       }
       public void SendAllUser()
       {
            var userSend = UserList.Where(u => u.ContextID == Context.ConnectionId).FirstOrDefault();
 
          foreach (var users in UserList)
           {
               Clients.All.addMessageUser(users.ContextIDusers.Name);
           }
       }
       public void GetUserInfo()
       {
          foreach (var users in UserList)
           {
               Clients.All.addMessageUser(users.ContextIDusers.Name);
           }
       } 
       public static List<UserInfo> UserList = new List<UserInfo>();
       public override Task OnConnected()
       {
           
           var user = UserList.SingleOrDefault(u => u.ContextID == Context.ConnectionId);
 
           if (user == null)
           {
               user = new UserInfo()
               {
                   Name = "User"+i,
                   ContextID = Context.ConnectionId
               };
               UserList.Add(user);
               i++;
 
           }
          
           Program.MainForm.WriteToConsole("Client connected: " + Context.ConnectionId);
           return base.OnConnected();
       }
       public override Task OnDisconnected()
       {
           var user = UserList.SingleOrDefault(u => u.ContextID == Context.ConnectionId);
           Clients.All.DeleteMessageUser(user.Name);
           UserList.Remove(user);
           Program.MainForm.WriteToConsole("Client disconnected: " + Context.ConnectionId);
           return base.OnDisconnected();
       }
   }

 

用戶端

 

public partial class WinFormsClient : Form
 {
     private String UserName { getset; }
     private IHubProxy HubProxy { getset; }
     const string ServerURI = "http://localhost:8080";
    private HubConnection Connection { getset; }
 
     internal WinFormsClient()
     {
         InitializeComponent();
         EventArgs e=new EventArgs();
         object sender = new object();
         SignInButton_Click(sender,e);
     }
 
     private void ButtonSend_Click(object senderEventArgs e)
     {
         if (listBox1.SelectedItem != null) { 
         HubProxy.Invoke("Send"listBox1.SelectedItem.ToString(), TextBoxMessage.Text);
         TextBoxMessage.Text = String.Empty;
         TextBoxMessage.Focus();
         }
     }
 
     private async void ConnectAsync()
     {
         Connection = new HubConnection(ServerURI);
         Connection.Closed += Connection_Closed;
         HubProxy = Connection.CreateHubProxy("MyHub");
         HubProxy.On<stringstring>("AddMessage", (messagemessageUserInfo=>
             this.Invoke((Action)(() =>
                 RichTextBoxConsole.AppendText(String.Format("{0}: {1}" + Environment.NewLinemessagemessageUserInfo))
             ))
         );
         HubProxy.On<stringstring>("AddMessageUser", (namemessage=>
            this.Invoke((Action)(() =>
                MakeUserList(namemessage)
            ))
        );
         HubProxy.On<string>("DeleteMessageUser", (name=>
            this.Invoke((Action)(() =>
                DeleteUserList(name)
            ))
        );
         try
         {
 
             await Connection.Start();
         }
         catch (HttpRequestException)
         {
             StatusText.Text = "Unable to connect to server: Start server before connecting clients.";
             return;
         }
 
         //Activate UI
         SignInPanel.Visible = false;
         ChatPanel.Visible = true;
         ButtonSend.Enabled = true;
         TextBoxMessage.Focus();
         RichTextBoxConsole.AppendText("Connected to server at " + ServerURI + Environment.NewLine);
 
         EventArgs e = new EventArgs();
         object sender = new object();
         button1_Click(sendere);
     }
 
     private void DeleteUserList(string name)
     {
         if (listBox1.Items.Contains(name))
         {
             listBox1.Items.Remove(name);
         }
     }
 
     private void MakeUserList(string namestring message)
     {
 
         RichTextBoxConsoleAll.AppendText(String.Format("{0}: {1}" + Environment.NewLinenamemessage));
         if (!listBox1.Items.Contains(message))
         {
             listBox1.Items.AddRange(new object[] {message});
         }
     }
    private void Connection_Closed()
     {
         this.Invoke((Action)(() => ChatPanel.Visible = false));
         this.Invoke((Action)(() => ButtonSend.Enabled = false));
         this.Invoke((Action)(() => StatusText.Text = "You have been disconnected."));
         this.Invoke((Action)(() => SignInPanel.Visible = true));
     }
 
     private void SignInButton_Click(object senderEventArgs e)
     {
         UserName = UserNameTextBox.Text;
         {
             StatusText.Visible = true;
             StatusText.Text = "Connecting to server...";
             ConnectAsync();
         }
     }
 
     private void WinFormsClient_FormClosing(object senderFormClosingEventArgs e)
     {
         if (Connection != null)
         {
             Connection.Stop();
             Connection.Dispose();
         }
     }
 
     private void button1_Click(object senderEventArgs e)
     {
         HubProxy.Invoke("SendAllUser");
         TextBoxMessage.Text = String.Empty;
         TextBoxMessage.Focus();
         HubProxy.Invoke("GetUserInfo");
 
     }
 }


如兩圖所示 一邊適用  HubProxy.Invoke("SendAllUser");
呼叫server的funcion
server也用 Client.All方法 打回給user  user再用
HubProxy.On<stringstring>("AddMessageUser", (namemessage=>
            this.Invoke((Action)(() =>             
            MakeUserList(namemessage)        
     ))
 );
指定client端要跑 MakeUserList(namemessage)這個function
就整體來說 挺好玩的 也減少SERVER跟CLIENT的負擔 跟傳輸資料量
 

arrow
arrow
    文章標籤
    SignalR
    全站熱搜

    丁滿 發表在 痞客邦 留言(0) 人氣()