I'm running a server with a localhost http://*:52080.
On the same computer, I'm run client and trying to connect to a local IP hub http://192.168.1.102:52080/signalr. Everything works well.
But if I run the client on another computer (from the same local network) and try to connect to http://192.168.1.102:52080/signalr, it does not connect. The client catches an exception ("System.AggregateException" in mscorlib.dll).
Port 52080 on the computer with the hub is open.
What could be the reason for the failure?
Server:
using System;
using Microsoft.Owin.Hosting;
public class Program
{
static void Main(string[] args)
{
string url = "http://*:52080";
using (WebApp.Start<Startup>(url))
{
Console.WriteLine("Server running at {0}\n", url);
Console.ReadLine();
}
}
}
Startup.cs
using Owin;
using Microsoft.Owin.Cors;
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
SGHub.cs
using System;
using System.Threading.Tasks;
using Microsoft.AspNet.SignalR;
using System.Collections.Generic;
public class SGHub : Hub
{
public static List<string> Users = new List<string>();
public override Task OnConnected()
{
Console.WriteLine("\nOnConnected {0}", Context.ConnectionId);
Users.Add(Context.ConnectionId);
Clients.Caller.broadcastMessage("Server:", "Successful connection");
Clients.Others.broadcastMessage("Server:", "New connection");
return (base.OnConnected());
}
}
Client:
using System;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.AspNet.SignalR.Client.Hubs;
using Newtonsoft.Json.Linq;
class Program
{
static void Main(string[] args)
{
string serverURL = "http://192.168.1.102:52080/signalr";
Console.WriteLine("Connection to {0}\n", serverURL);
HubConnection hubConnection = new HubConnection(serverURL);
IHubProxy myHubProxy = hubConnection.CreateHubProxy("StartGameHub");
myHubProxy.On<string, string>("Send", (name, message) => Console.Write("Recieved addMessage: " + name + ": " + message + "\n"));
myHubProxy.On("heartbeat", () => Console.Write("Recieved heartbeat \n"));
Subscription subscription = myHubProxy.Subscribe("broadcastMessage");
subscription.Received += SubscriptionData;
while (true)
{
string key = Console.ReadLine();
if (key.ToUpper() == "A")
{
try
{
Console.WriteLine("Start connect..");
hubConnection.Start().Wait();
}
catch (System.AggregateException e)
{
Console.WriteLine("Connected fauld :(");
}
}
}
}
private static void SubscriptionData(IList<JToken> obj)
{
Console.WriteLine(obj[1].ToString());
}
}
Related
is it even possible to send a message to all(or selected) connected clients connected to the hub? I mean from the server side to all clients. I can get clients data to server window, but when I enter and try to send from server side nothing happens on clients window. How to push notifications to all straight from server app?
Server:
namespace SignalRHub
{
class Program
{
static void Main(string[] args)
{
string url = #"http://localhost:8080/";
using (WebApp.Start<Startup>(url))
{
Console.WriteLine(string.Format("Server running at {0}", url));
Console.ReadLine();
while (true)
{
// get text to send
Console.WriteLine("Enter your message:");
string line = Console.ReadLine();
// Get hub context
IHubContext ctx = GlobalHost.ConnectionManager.GetHubContext<TestHub>();
// call addMessage on all clients of context
ctx.Clients.All.addMessage(line);
// pause to allow clients to receive
Console.ReadLine();
}
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
[HubName("TestHub")]
public class TestHub : Hub
{
public void SendMsg(string message)
{
Console.WriteLine(message);
}
}
}
}
Client:
namespace SignalRClient
{
class Program
{
static void Main(string[] args)
{
IHubProxy _hub;
string url = #"http://localhost:8080/";
try
{
Console.WriteLine("Connecting to: " +url);
var connection = new HubConnection(url);
_hub = connection.CreateHubProxy("TestHub");
connection.Start().Wait();
Console.WriteLine();
Console.WriteLine();
Console.WriteLine("---------- Connection OK.");
Console.WriteLine();
}
catch (Exception e)
{
Console.WriteLine("------------ Connection FAILED: ");
Console.WriteLine(e);
throw;
}
string line = null;
while ((line = System.Console.ReadLine()) != null)
{
_hub.Invoke("SendMsg", line).Wait();
}
Console.Read();
}
}
}
Server Code
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Runtime.Serialization.Formatters.Binary;
using Global;
using System.IO;
namespace Server
{
class Program
{
static List<string> BlackList = new List<string>();
static List<TcpClient> Clients = new List<TcpClient>();
static object _lock = new object();
static BinaryFormatter Formatter = new BinaryFormatter();
static TcpListener Server;
static void Main(string[] args)
{
Init();
Console.ReadLine();
}
/*
* Initiate the server and start listening
*/
static void Init()
{
Server = new TcpListener(IPAddress.Any, 7777);
Server.Start();
Task.Factory.StartNew(() => Listen());
}
/*
* Listens to new incoming connections
* Assigns the new client a worker who will listen to it's requests
* Add the client to the list of active clients
*/
static void Listen()
{
for (;;)
{
TcpClient client = Server.AcceptTcpClient();
lock(_lock)
Clients.Add(client);
Task.Factory.StartNew(() => Work(client));
Thread.Sleep(100);
}
}
/*
* Listens to incoming requests from a client and sends a response back if necessary
* On disconnect remove client from active clients list
*/
static void Work(TcpClient client)
{
while (client.Connected)
{
NetworkStream stream = client.GetStream();
try
{
dynamic request = Formatter.Deserialize(stream);
Response response = HandleRequest(request);
if(response != null)
Formatter.Serialize(stream, response);
}
catch(Exception ex)
{
Console.Write(ex.Message);
}
}
lock (_lock)
Clients.Remove(client);
}
/*
* Handles File Transfer Requests
*/
static Response HandleRequest(FileTransferRequest request)
{
string file = request.File;
FileTransferResponse response;
if (File.Exists($"{Environment.CurrentDirectory}\\{file}"))
response = new FileTransferResponse(File.ReadAllBytes(file));
else
response = new FileTransferResponse(null);
return response;
}
}
}
Client Code
using System;
using System.Net.Sockets;
using System.Runtime.Serialization.Formatters.Binary;
using Global;
using System.IO;
namespace Client
{
class Program
{
static TcpClient Server;
static void Main(string[] args)
{
string file = args[0];
string output = args[1];
Init();
NetworkStream stream = Server.GetStream();
BinaryFormatter formatter = new BinaryFormatter();
//Request
FileTransferRequest request = new FileTransferRequest(file);
formatter.Serialize(stream, request);
//Get Response
FileTransferResponse response = (FileTransferResponse) formatter.Deserialize(stream);
if (response.File == null)
Console.Write("File not found");
else
{
File.WriteAllBytes(output, response.File);
Console.Write("Success");
}
Console.ReadLine();
}
static void Init()
{
try
{
Server = new TcpClient("lordfrostbyte.webhop.me", 7777);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
Console.ReadLine();
Environment.Exit(-1);
}
}
}
}
Global Library Code
namespace Global
{
[Serializable]
public abstract class Request
{
}
[Serializable]
public class FileTransferRequest : Request
{
public string File;
public FileTransferRequest(string File)
{
this.File = File;
}
}
[Serializable]
public abstract class Response
{
}
[Serializable]
public class FileTransferResponse : Response
{
public byte[] File;
public FileTransferResponse(byte[] File)
{
this.File = File;
}
}
}
This is my code... It's not working !
But I have configured port forwarding
I have also disabled my firewall
My guess is something is wrong with windows. However I do not want to format my computer in order to solve this. I would much appreciate any input that would lead to solving this issue. I have had this issue for a while and I was wondering if anyone else has had a similar issue and if anyone has ever solved this. At the moment I have no clue how to even troubleshoot this issue. Do note that if I host the server on LAN and connect to LAN it works perfectly.
I had to reinstall pcap drivers.
I'm doing a small windows service, it reads from a web service and stores the data in a local database, however, it does not finish executing the while (while it's a service), when I'm debugging it in vs 15 it works perfectly , Follow the code below.
PS: The code I used to debug I comment it before it starts, it arrives to enter the while, but only the first line and does not check the rest.
Program.cs
using System.ServiceProcess;
namespace rdi_server.service
{
static class Program
{
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
}
Service1.CS
using System;
using System.Configuration;
using System.ServiceProcess;
using System.Threading;
namespace rdi_server.service
{
public partial class Service1 : ServiceBase
{
private Thread _thread;
private Updater _updater = new Updater();
private readonly int Interval = Convert.ToInt32(ConfigurationManager.AppSettings["timer"]);
private readonly string Connection = ConfigurationManager.AppSettings["connection"];
private readonly Connector _usuarioConnector;
private readonly Connector _bandaConnector;
private readonly Connector _generoConnector;
private readonly Connector _musicaConnector;
public Service1()
{
_usuarioConnector = new Connector("UsuarioBase");
_bandaConnector = new Connector("BandaBase");
_generoConnector = new Connector("GeneroBase");
_musicaConnector = new Connector("MusicaBase");
InitializeComponent();
}
protected override void OnStart(string[] args)
{
StartDebug();
}
public void StartDebug()
{
_thread = new Thread(OnTime);
_thread.Name = "My Worker Thread";
_thread.Start();
}
protected override void OnStop()
{
}
protected void OnTime()
{
while (true)
{
EventLog.WriteEntry("Dentro do WHILE foi executado!");
_updater.Do(Connection, _usuarioConnector, _generoConnector, _bandaConnector, _musicaConnector);
EventLog.WriteEntry("Fim do while");
Thread.Sleep(Interval);
}
}
}
}
Updater.CS
using rdi_musica.core;
using System.Collections.Generic;
using System.Data.SqlClient;
namespace rdi_server.service
{
class Updater
{
public void Do(string Connection,
Connector usuario,
Connector genero,
Connector banda,
Connector musica)
{
var usuarios = Loader.LoadUsuarios(usuario);
var generos = Loader.LoadGeneros(genero);
var bandas = Loader.LoadBandas(banda);
var musicas = Loader.LoadMusicas(musica);
using (var connection = new SqlConnection(Connection))
{
connection.Open();
foreach (var _usuario in usuarios)
{
DomainDAO.InsertUsuario(connection, _usuario);
}
foreach (var _genero in generos)
{
DomainDAO.InsertGenero(connection, _genero);
}
foreach (var _banda in bandas)
{
DomainDAO.InsertBanda(connection, _banda);
}
foreach (var _musica in musicas)
{
DomainDAO.InsertMusica(connection, _musica);
}
}
}
}
}
What's probably happening is you have an unhandled exception happening somewhere, which is breaking out of your while loop.
You can use the windows event log in combination with try-catch to log your errors, without breaking your infinite loop:
protected void OnTime()
{
while (true)
{
try
{
EventLog.WriteEntry("Dentro do WHILE foi executado!");
_updater.Do(Connection, _usuarioConnector, _generoConnector, _bandaConnector, _musicaConnector);
EventLog.WriteEntry("Fim do while");
}
catch (Exception ex)
{
this.EventLog.WriteEntry("ERROR: " + ex.GetType().ToString() + " : " + ex.Message + " : " + ex.StackTrace, EventLogEntryType.Error);
}
Thread.Sleep(Interval);
}
}
I wrote this C# code to have namedPipeServer and NamedPipeClient, with Asynchronous read and write settings, connect to each other. Both code runs perfectly on visual studio 2010 that I am using with read and write working well without any application freeze during runtime.
But I want the client side running in unity3d. The problem I encounter is in client side code implemented in Unity3D. When I use Write_to_Server_Async(string message), read in the server side is not invoked and is only invoked when I quit Unity3d (I have end its process typically). I can tell something wrong with Unity3D, because the exact code works perfectly in visual studio, so I know my code is implemented the right way. I have heard about how unity3d does not really use real threads unless user manually creates one but even that has not solved the problem. My speculation is Unity3D developers might have created their version of .NET library 3.5 (sounds bizzare (does explain why they still haven't adopted 4.5)) or somehow they must have structured their library in a way that by default functions like NamedPipeClientStream.BeginWrite cannot create its own real thread. But then again I am not sure if its the problem with threads.
At the moment, I would like anyone to come up with good explanation.
Make sure to replace Debug.WriteLine to UnityEngine.Debug.Log in unity3d.
Below is Client Main method code and class
class PipeClient
{
private static Asynchronus_NamedPipe_Client client;
static void Main(string[] args)
{
client = new Asynchronus_NamedPipe_Client("mypipe7055");
while (client.Is_connected_to_server()) {
if (Console.ReadKey().Key == ConsoleKey.T)
{
client.Write_to_Server_Async("NEX CLIENT");
}
}
}
}
Asynchronus_NamedPipe_Client class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System;
using System.IO;
using System.IO.Pipes;
using System.Text;
using System.Security.Principal;
using System.Diagnostics;
using System.Threading;
namespace NamedPipes_CLIENT
{
public class Asynchronus_NamedPipe_Client
{
public readonly string pipe_address;
private System.IO.Pipes.NamedPipeClientStream clientStream;
public bool filter_message = true;
private string Server_Message = null;
public event ASYNC_pipe_status_callback ASYNC_external_Write_Completed;
public event ASYNC_pipe_status_callback ASYNC_external_Read_Completed;
public delegate void ASYNC_pipe_status_callback(string message);
private byte[] read_buffer = new byte[1024];
private byte[] write_buffer = new byte[1024];
private IAsyncResult read_result;
private IAsyncResult write_result;
private int read_id = 1;
public Asynchronus_NamedPipe_Client(string pipe_address)
{
try
{
this.pipe_address = pipe_address;
// if(clientStream.IsConnected){UnityEngine.Debug.Log("Server Already Running");}else{}
clientStream = new NamedPipeClientStream(".", this.pipe_address, PipeDirection.InOut, PipeOptions.Asynchronous);
clientStream.Connect(1);
if (clientStream.IsConnected)
{
Console.WriteLine("Connected to Server");
Read_from_Server_Async();
}
else { Console.WriteLine("Could NOT connect to Server"); }
}
catch (Exception oEX) { Console.WriteLine("Application Pipe Error: "+oEX.Message); }
}
public void Write_to_Server_Async(string message)
{
if (clientStream != null)
{
if (clientStream.CanWrite && clientStream.IsConnected)
{
clientStream.WaitForPipeDrain();
ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);
clientStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 1);
} else { close_pipe(); }
}
}
public void Read_from_Server_Async()
{
if (clientStream.CanRead && clientStream.IsConnected)
{
clientStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 2);
} else { close_pipe(); }
}
private void Async_Write_Completed(IAsyncResult result)
{
clientStream.EndWrite(result);
Debug.WriteLine("Written To Server => " + ASCIIEncoding.ASCII.GetString(write_buffer));
// close_pipe();
}
private void Async_Read_Completed(IAsyncResult result)
{
clientStream.EndRead(result);
Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
this.Server_Message.Trim();
Console.WriteLine("Received from Server => " + Server_Message);
Debug.WriteLine("Received from Server => " + Server_Message);
if (clientStream.CanRead && clientStream.IsConnected)
{
Read_from_Server_Async();
}
else { close_pipe(); }
}
public Boolean Is_connected_to_server() {
return clientStream.IsConnected;
}
public void close_pipe()
{
if (clientStream != null)
{
if (clientStream.IsConnected)
{
clientStream.Close();
clientStream.Dispose();
Debug.WriteLine(" Pipe Closed");
}
}
}
}
}
Server side Main method implementation
static void Main(string[] args)
{
Asynchronus_NamedPipe_Server Async_server = new Asynchronus_NamedPipe_Server("mypipe7055");
while (true)
{
do
{
Async_server.Write_to_Client_Async("yeye");
Console.WriteLine("escape key");
} while (Console.ReadKey(true).Key != ConsoleKey.Escape);
}
}
Server Side Class -----
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.ComponentModel;
using System.Diagnostics;
namespace Application_Pipe
{
public class Asynchronus_NamedPipe_Server
{
public readonly string pipe_address;
private System.IO.Pipes.NamedPipeServerStream namedPipeServerStream;
private string Server_Message;
public delegate void ASYNC_pipe_status_callback(string message);
private byte[] read_buffer = new byte[1024];
private byte[] write_buffer = new byte[1024];
public Asynchronus_NamedPipe_Server(string pipe_address)
{
try
{
this.pipe_address = pipe_address;
namedPipeServerStream = new NamedPipeServerStream(this.pipe_address,
PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous); //new NamedPipeServerStream(pipe_address);
Console.WriteLine("Connecting to Client...");
namedPipeServerStream.WaitForConnection();
Console.WriteLine("Connected to Client");
Read_from_Client_Async();
}
catch (Exception oEX) { Console.WriteLine(oEX.Message); }
}
public void Write_to_Client_Async(string message)
{
if (namedPipeServerStream != null)
{
if (namedPipeServerStream.CanWrite && namedPipeServerStream.IsConnected)
{
namedPipeServerStream.WaitForPipeDrain();
ASCIIEncoding.ASCII.GetBytes(message).CopyTo(write_buffer,0);
namedPipeServerStream.BeginWrite(write_buffer, 0, write_buffer.Length, new AsyncCallback(Async_Write_Completed), 2);
}
else { close_pipe(); }
}
}
public void Read_from_Client_Async()
{
if (namedPipeServerStream != null)
{
if (namedPipeServerStream.CanRead && namedPipeServerStream.IsConnected)
{
namedPipeServerStream.BeginRead(read_buffer, 0, read_buffer.Length, new AsyncCallback(Async_Read_Completed), 1);
} else { close_pipe(); }
}
}
private void Async_Read_Completed(IAsyncResult result)
{
namedPipeServerStream.EndRead(result);
this.Server_Message = ASCIIEncoding.ASCII.GetString(read_buffer);
this.Server_Message.Trim();
Debug.WriteLine("Received from Client => " + this.Server_Message+" <=REnd");
Read_from_Client_Async();
}
private void Async_Write_Completed(IAsyncResult result)
{
namedPipeServerStream.EndWrite(result);
Debug.WriteLine("Written To Client => " + ASCIIEncoding.ASCII.GetString(write_buffer));
}
public Boolean Is_connected_to_server()
{
return this.namedPipeServerStream.IsConnected;
}
public void close_pipe()
{
if(namedPipeServerStream.IsConnected){
namedPipeServerStream.Disconnect();
}
namedPipeServerStream.Close();
namedPipeServerStream.Dispose();
Debug.WriteLine(" Pipe Closed");
}
} //------class End
}
I'm using SignalR 2.0 self-hosted with OWIN. I am trying to modify the SignalR ConnectionTimeout property, but it does not seem to work with the OWIN Startup class.
Current Attempt
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Cors;
using Owin;
namespace Test
{
internal class Startup
{
public void Configuration(IAppBuilder app)
{
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(10);
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
}
I have also tried to just add my own Global.asax file copied from another project. However, I can't seem to resolve the System.Web.HttpApplication extension.
using System;
using Microsoft.AspNet.SignalR;
namespace Test
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalHost.Configuration.ConnectionTimeout = TimeSpan.FromSeconds(10);
}
}
}
Any suggestions how to tackle this?
Link to docs: SignalR Configuration
You need to call GlobalHost before startup is called. Basically, if your code looks like this:
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using Microsoft.Owin.Cors;
namespace SignalRSelfHost
{
class Program
{
static void Main(string[] args)
{
// This will *ONLY* bind to localhost, if you want to bind to all addresses
// use http://*:8080 to bind to all addresses.
// See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx
// for more information.
string url = "http://localhost:8080";
using (WebApp.Start(url))
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
GlobalHost.Configuration.ConnectionTimeout = new TimeSpan(0, 0, 110);
GlobalHost.Configuration.DisconnectTimeout = new TimeSpan(0, 0, 60);
GlobalHost.Configuration.KeepAlive = new TimeSpan(0, 0, 5);
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
}
}
it should look like this:
using System;
using Microsoft.AspNet.SignalR;
using Microsoft.Owin.Hosting;
using Owin;
using Microsoft.Owin.Cors;
namespace SignalRSelfHost
{
class Program
{
static void Main(string[] args)
{
// This will *ONLY* bind to localhost, if you want to bind to all addresses
// use http://*:8080 to bind to all addresses.
// See http://msdn.microsoft.com/en-us/library/system.net.httplistener.aspx
// for more information.
string url = "http://localhost:8080";
GlobalHost.Configuration.ConnectionTimeout = new TimeSpan(0, 0, 110);
GlobalHost.Configuration.DisconnectTimeout = new TimeSpan(0, 0, 60);
GlobalHost.Configuration.KeepAlive = new TimeSpan(0, 0, 5);
using (WebApp.Start(url))
{
Console.WriteLine("Server running on {0}", url);
Console.ReadLine();
}
}
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
public class MyHub : Hub
{
public void Send(string name, string message)
{
Clients.All.addMessage(name, message);
}
}
}