SignalR - SERVIDOR Y CLIENTE CON USUARIOS REGISTRADOS

// Proyecto Servidor ------------------>
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Microsoft.Owin.Hosting;
using Owin;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace SignalRChat
{

    public partial class PushSignalRServer : Form
    {

        private IDisposable SignalR { get; set; }
        const string ServerURI ="https://+:8082"; //--> puerto de escucha del servidor

        public List<ConnectedClients> ConnectedUsers = new List<ConnectedClients>();
      
        internal PushSignalRServer()
        {
            InitializeComponent();
        }

        private void ButtonStart_Click(object sender, EventArgs e)
        {
            WriteToConsole("Starting server..." + DateTime.Now.ToString("dd/MM/yyyy HH:mm"CultureInfo.CreateSpecificCulture("es-ES")) );
            ButtonStart.Enabled = false;
            Task.Run(() => StartServer());
        }
            
             
        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);
            notifyIconOff.Visible = false ;
            notifyIconOn.Visible = true ;
        }
     
        internal void WriteToConsole(String message)
        {
            if (RichTextBoxConsole.InvokeRequired)
            {
                this.Invoke((Action)(() =>
                    WriteToConsole(message)
                ));
                return;
            }

            RichTextBoxConsole.AppendText(message + Environment.NewLine);
        }

        private void WinFormsServer_FormClosing(object sender, FormClosingEventArgs e)
        {
           
            if (SignalR != null)
            {
                SignalR.Dispose();
            }
        }

        private void WinFormsServer_Load(object sender, EventArgs e)
        {
                      
            WriteToConsole("Starting server..." + DateTime.Now.ToString("dd/MM/yyyy HH:mm", CultureInfo.CreateSpecificCulture("es-ES")));
            ButtonStart.Enabled = false;
            Task.Run(() => StartServer());
        }

       
    }

    class Startup
    {
        public void Configuration(IAppBuilder app)
        {
           app.UseCors(CorsOptions.AllowAll);
           app.MapSignalR();
        }
    }
  
    public class MyHub : Hub
    {

     //Función para enviar mensaje de usuario emisor (nombre y compañia) a usuario receptor (nombre y compañia)
     public void Send(string nameFrom, string companyFrom, string message, string nameTo, string companyTo)
        {
           
            if (nameTo.ToUpper() == "ALL" || nameTo.ToUpper() == "TODOS")
                {
                  
                         Send(nameFrom, message);
                }
                else
                {
               
                    if (Program.MainForm.ConnectedUsers != null)
                    {
                       var exists =
                       from ConnectedClients e in Program.MainForm.ConnectedUsers
                       where e.Name == nameTo && e.Company == companyTo
                       select e;

                       if (exists.Count() == 0)
                        {
                        }
                        else
                        {
                            foreach (var UserExist in exists)
                            {
                                Clients.Client(UserExist.Id).addMessage(nameFrom, message);
                            }
                        }
                    }
                    else
                    {
                    }
                }
        }

        public override Task OnConnected()
        {
                               
            return base.OnConnected();
        }

         public override Task OnDisconnected(bool stopCalled)
        {
            var exists =
                from ConnectedClients e in Program.MainForm.ConnectedUsers
                where e.Id == Context.ConnectionId
                select e;
            if (exists.Count() == 0)
            {
            }
            else
            {
                foreach (var UserExist in exists)
                {
                    Program.MainForm.WriteToConsole("Client disconnected: " + UserExist.Name);
                }
            }

            Program.MainForm.ConnectedUsers.RemoveAll(u => u.Id == Context.ConnectionId);

            return base.OnDisconnected(true);
        }

        //Función para identificar al usuario en servidor (añadir al cliente a la lista ConnectedClients) -->
        public void WhoIam(string MyName, string MyCompany)
        {
            if (string.IsNullOrEmpty(MyCompany))
            {
            }
            else
            {
                if (MyCompany.Substring(MyCompany .Length -1)==".")
                {
                    MyCompany = MyCompany.Substring(0, MyCompany.Length - 1);
                }
            }
           
               if (Program.MainForm.ConnectedUsers != null)
                {
                    if (Program.MainForm.ConnectedUsers.Count()> 0 )
                    {
                            var exists =
                            from ConnectedClients e in Program.MainForm.ConnectedUsers
                            where e.Name == MyName && e.Company == MyCompany && e.Id != Context.ConnectionId
                            select e;

                            if (exists.Count() > 0)
                            {
                                Program.MainForm.ConnectedUsers.RemoveAll(u => u.Name == MyName);
                                addConnectedUsers(MyName, MyCompany);
                            }
                            else
                           {
                                addConnectedUsers(MyName, MyCompany);
                           }
                    }
                    else
                    {
                        addConnectedUsers(MyName, MyCompany);
                    }
                }
                else
                {
                    addConnectedUsers(MyName, MyCompany);
                }
        }

        private void addConnectedUsers(string Name, string Company)
        {

            ConnectedClients newUser = new ConnectedClients();
            newUser.Id = Context.ConnectionId;
            newUser.Name = Name;
            newUser.Company = Company;
            newUser.TimeStamp = DateTime.Now;

            Program.MainForm.ConnectedUsers.Add(newUser);

            Program.MainForm.WriteToConsole("Client connected: " + Name);
        }

        public void Send(string name, string message)
        {
            Clients.All.addMessage(name, message);
        }

    }

   
    public class ConnectedClients
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Company { get; set; }
        public DateTime TimeStamp { get; set; }
              
    }
}

//Proyecto Cliente ------------à
using Microsoft.AspNet.SignalR.Client;
using System;
using System.Net.Http;
using System.Windows.Forms;

namespace WinFormsClient
{
    public partial class WinFormsClient : Form
    {

        private String UserName { get; set; }
        private String CompanyName { get; set; }
        private IHubProxy HubProxy { get; set; }
        const string ServerURI = "https://miservidor.net:8082/signalr";

        private HubConnection Connection { get; set; }

        internal WinFormsClient()
        {
            InitializeComponent();
        }
       

        private async void ConnectAsync()
        {
            Connection = new HubConnection(ServerURI);
            Connection.Closed += Connection_Closed;
            HubProxy = Connection.CreateHubProxy("MyHub");

            HubProxy.On<string, string>("AddMessage", (name, message) =>
                this.Invoke((Action)(() =>
                    RichTextBoxConsole.AppendText(String.Format("{0}: {1}" + Environment.NewLine, name, message))
                ))
            );

            try
            {
                await Connection.Start();
            }
            catch (HttpRequestException)
            {
                StatusText.Text = "Unable to connect to server: Start server before connecting clients.";
                //No connection
                return;
            }

            SignInPanel.Visible = false;
            ChatPanel.Visible = true;
            ButtonSend.Enabled = true;
            TextBoxMessage.Focus();
            RichTextBoxConsole.AppendText("Connected to server at " + ServerURI + Environment.NewLine);
            identify();
        }

        private void identify() //Me identifico (UserName + CompanyName)
        {
            HubProxy.Invoke("WhoIam", UserName, CompanyName);
            this.Text = UserName + "(" + CompanyName + ")";
        }

        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));
        }

        //Este Botón permite conectarme al servidor
        private void SignInButton_Click(object sender, EventArgs e)
        {
            UserName = UserNameTextBox.Text;
            CompanyName = CompanyTextbox.Text;
            //Connect to server (use async method to avoid blocking UI thread)
            if (!String.IsNullOrEmpty(UserName) && !String.IsNullOrEmpty(CompanyName))
            {
                StatusText.Visible = true;
                StatusText.Text = "Connecting to server...";
                ConnectAsync();
            }
        }

        private void WinFormsClient_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (Connection != null)
            {
                Connection.Stop();
                Connection.Dispose();
            }
        }

        //Enviar mensaje --->;
        private void ButtonSend_Click(object sender, EventArgs e)
        {
            //Invocamos a Send identificándonos (usuario y empresa) e identificando al receptor (usuario y empresa)
            HubProxy.Invoke("Send", UserName, CompanyName, TextBoxMessage.Text, txtPara.Text, txtCompany.Text.Trim());
            TextBoxMessage.Text = String.Empty;
            TextBoxMessage.Focus();
        }

    }

LLAMADA POST A SERVICIO

Necesitas referenciar a la dll Newtonsoft.Json.dll http://www.newtonsoft.com/json para deserialización de la respuesta al servicio (en json)

'Llamada post a: http://api.test.es/v1/post_insert_value para insertar los valores value1, value2, value3
    'Respuesta esperada: {"data":{"has_result":"yes"}}


    Public Class ContainerInsertResult
        Public data As InsertResult
    End Class

    Public Class InsertResult
        Public has_result As String
    End Class

    Sub post()

        Try

            Dim request As WebRequest = WebRequest.Create("http://api.test.es/v1/post_insert_value")
            request.Method = "POST"

            Dim postData As String = _
                "&value1=test" & _
                "&value2=test2" & _
                "&value3=test3"


            Dim byteArray As Byte() = Encoding.UTF8.GetBytes(postData)
            request.ContentType = "application/x-www-form-urlencoded"

            Dim response As WebResponse
            Dim dataStream As Stream

            dataStream = request.GetRequestStream()
            dataStream.Write(byteArray, 0, byteArray.Length)
            dataStream.Close()

            response = request.GetResponse()
            dataStream = response.GetResponseStream()

            Dim reader As New StreamReader(dataStream)
            Dim responseFromServer As String = reader.ReadToEnd()

            Dim parsedResponse As ContainerInsertResult = JsonConvert.DeserializeObject(Of ContainerInsertResult)(responseFromServer)

            Dim respuesta As InsertResult = parsedResponse.data

            MsgBox(respuesta.has_result)

        Catch ex As WebException
            If (ex.Status = WebExceptionStatus.ProtocolError) Then
                Dim responsee As WebResponse = ex.Response

                Using (responsee)
                    Dim httpResponse As HttpWebResponse = CType(responsee, HttpWebResponse)
                    Dim statusCode As HttpStatusCode = httpResponse.StatusCode

                    Dim myStreamReader As StreamReader = New StreamReader(responsee.GetResponseStream())
                    Using (myStreamReader)
                        Dim ResponseText As String = myStreamReader.ReadToEnd

                        MessageBox.Show(ResponseText)

                    End Using

                End Using
            End If
        End Try


    End Sub

LLAMADA GET A SERVICIO

Necesitas referenciar a la dll Newtonsoft.Json.dll http://www.newtonsoft.com/json para deserialización de la respuesta al servicio (en json)

'Llamada get a: http://api.test.es/v1/get_program_has_result?programId=test&programName=prueba
    'Respuesta esperada: {"data":{"has_result":"yes"}}

    Public Class ValidateResult
        Public has_result As String
    End Class
    Public Class ContainerValidateResult
        Public data As ValidateResult
    End Class

    Sub getResult()

        Try

            Dim webClient As New System.Net.WebClient
            Dim jsonString As String = webClient.DownloadString("http://api.test.es/v1/get_program_has_result?programId=test&programName=prueba")
            Dim respuesta As ContainerValidateResult = JsonConvert.DeserializeObject(Of ContainerValidateResult)(jsonString)

            MsgBox(respuesta.data.has_result)

        Catch ex As WebException
            If (ex.Status = WebExceptionStatus.ProtocolError) Then
                Dim responsee As WebResponse = ex.Response

                Using (responsee)

                    Dim httpResponse As HttpWebResponse = CType(responsee, HttpWebResponse)
                    Dim statusCode As HttpStatusCode = httpResponse.StatusCode

                    Dim myStreamReader As StreamReader = New StreamReader(responsee.GetResponseStream())
                    Using (myStreamReader)
                        Dim ResponseText As String = ""
                        ResponseText = myStreamReader.ReadToEnd()
                        ResponseText = ResponseText
                        MessageBox.Show(ResponseText)
                    End Using

                End Using
            End If
        End Try


    End Sub

INVOCAR AL DISEÑADOR DESDE UN SEGUNDO HILO DE EJECUCIÓN

Public Delegate Sub changeIconStatusInvoker(index As Integer)

Private WithEvents changeIconStatusWorker As System.ComponentModel.BackgroundWorker

'Cambiamos el icono en el campo correspondiente de la fila de un datagridview (dgUsers), segun el valor del campo status

Private Sub changeIconStatusWorkerWorker_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles changeIconStatusWorker.DoWork
       
     Dim d As New changeIconStatusInvoker(AddressOf Me.changeIcon)
     For i As Integer = 0 To dgUsers.RowCount - 1

           Me.Invoke(d, New Object() {i}) 
            
     Next

 End Sub

 Function changeIcon(index As Integer) As Boolean
     
     If dgUsers("statusID", index).Value = "1" Then
        dgUsers("status", index).Value = My.Resources.chat_on
     Else
        dgUsers("status", index).Value = My.Resources.chat_off
     End If
           
     Return True


 End Function

DESCARGAR IMAGEN

Function DownloadImage(_URL As String) As Image

        Dim _tmpImage As Image = Nothing

        Try

            Dim _HttpWebRequest As System.Net.HttpWebRequest = CType(System.Net.HttpWebRequest.Create(_URL), System.Net.HttpWebRequest)
            _HttpWebRequest.AllowWriteStreamBuffering = True

            _HttpWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)"
            _HttpWebRequest.Referer = "http://www.google.com/"

            _HttpWebRequest.Timeout = 20000


            Dim _WebResponse As System.Net.WebResponse = _HttpWebRequest.GetResponse()
            Dim _WebStream As System.IO.Stream = _WebResponse.GetResponseStream()


            _tmpImage = Image.FromStream(_WebStream)

            _WebResponse.Close()
            _WebStream.Close()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

        Return _tmpImage
    End Function


CREAR ENTRADA EN EL REGISTRO

'HKEY_LOCAL_MACHINE
Function createRegistryKey_LocalMachine(KeyName As String, valueName As String, value As String) As Boolean

        Try
            Dim ExistKey As String = Microsoft.Win32.Registry.GetValue("HKEY_LOCAL_MACHINE\" & KeyName, valueName, "Not Exist")

            If ExistKey = "Not Exist" Then
                Dim key As Microsoft.Win32.RegistryKey
                key = Microsoft.Win32.Registry.LocalMachine.CreateSubKey("Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION")
                key.SetValue(valueName, value, Microsoft.Win32.RegistryValueKind.DWord)
                key.Close()

                Return True
            Else
                Return False
            End If

        Catch ex As Exception
            Return False
        End Try


    End Function


createRegistryKey_LocalMachine("Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION", "miAplicacion.exe", "8888")
createRegistryKey_LocalMachine("SOFTWARE\Wow6432Node\Microsoft\Internet Explorer\MAIN\FeatureControl\FEATURE_BROWSER_EMULATION", "miAplicacion.exe", "8888")