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();
}
}
}
Related
I'm trying use SignalR with IP address but i am not able to connect with any ip adresses. Firstly i tried for server URI this. "http://127.0.0.1:8080/signalr" but i take some errors. Client app says unable to connect server. what could be reason of this?
public partial class WinFormsServer : Form
{
private IDisposable SignalR { get; set; }
const string ServerURI = "http://localhost:8080/signalr";
private void ButtonStart_Click(object sender, EventArgs e)
{
WriteToConsole("Starting server...");
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);
//Re-enable button to let user try to start server again
this.Invoke((Action)(() => ButtonStart.Enabled = true));
return;
}
this.Invoke((Action)(() => ButtonStop.Enabled = true));
WriteToConsole("Server started at " + ServerURI);
}
class Startup
{
public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}
}
}
I changed my startup class with this code like Rick van den Bosch's solve. But i can't connect any ip address still.
public class Startup
{
public void Configuration(IAppBuilder app)
{
app.Map("/signalr", map =>
{
map.UseCors(CorsOptions.AllowAll);
var hubConfiguration = new HubConfiguration { };
map.RunSignalR(hubConfiguration);
});
}
}
I wrote a client-server app, this is a console chat application for many clients. When only one client is connected, the application works well, but when two or more clients are connected I have a bug, after sending one message to the second client, he lost connection to the server and only first client can send a message to the server...
I used Task for asynchronous operations like listening port and sending messages. When one client sends a message to the server, it adds it to the list messages and resends to all clients to refresh all windows.
Server application:
using System;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Server
{
class Program
{
private static List<Client> clients = new List<Client>();
private static TcpListener listener = null;
private static StreamReader reader = null;
private static StreamWriter writer = null;
private static List<Task> clientTasks = new List<Task>();
private static List<string> messages = new List<string>();
public static void Main()
{
Console.Title = "Server";
try
{
listener = new TcpListener(IPAddress.Parse("127.0.0.1"), 8080);
listener.Start();
Console.WriteLine("Server started...");
var connectTask = Task.Run(() => ConnectClients());
//var listenTask = Task.Run(() => ListenClients());
Task.WaitAll(connectTask);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
if (listener != null)
{
listener.Stop();
}
}
}
private static void ConnectClients()
{
Console.WriteLine("Waiting for incoming client connections...");
while (true)
{
if (listener.Pending()) //if someone want to connect
{
clients.Add(new Client(listener.AcceptTcpClient(), "Client: " + (clients.Count + 1)));
Console.WriteLine(clients[clients.Count - 1].clientName + " connected to server.");
var newClientTask = Task.Run(() => HandleClient(clients[clients.Count - 1]));
clientTasks.Add(newClientTask); //start new task for new client
}
}
}
private static void HandleClient(Client TCPClient)
{
Console.WriteLine("Starting handle client");
string s = string.Empty;
writer = new StreamWriter(TCPClient.client.GetStream());
reader = new StreamReader(TCPClient.client.GetStream());
try
{
while (!(s = reader.ReadLine()).Equals("Exit") || (s == null))
{
if(!TCPClient.client.Connected)
{
Console.WriteLine("Client disconnected.");
clients.Remove(TCPClient);
}
Console.WriteLine("From client: " + TCPClient.clientName + " -> " + s);
messages.Add(TCPClient.clientName + ": " + s); //save new message
//Console.WriteLine(s);
foreach (Client c in clients) //refresh all connected clients
{
c.writer.WriteLine("%C"); //clear client
foreach (string msg in messages)
{
c.writer.WriteLine(msg);
c.writer.Flush();
}
}
}
//CloseServer();
}
catch (Exception e) { Console.WriteLine(e); }
Console.WriteLine("ending handle client");
}
private static void CloseServer()
{
reader.Close();
writer.Close();
clients.ForEach(tcpClient => tcpClient.client.Close());
}
}
}
Client information class:
using System.Net.Sockets;
using System.IO;
namespace Server
{
class Client
{
public TcpClient client;
public StreamWriter writer;
public string clientName;
public Client(TcpClient client, string clientName)
{
this.client = client;
writer = new StreamWriter(client.GetStream());
this.clientName = clientName;
}
}
}
Client application:
using System.Net.Sockets;
using System.Net;
using System.IO;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace Client
{
class Program
{
private static TcpClient client = new TcpClient();
private static StreamReader reader;
private static StreamWriter writer;
private static bool refresh;
private static List<string> messages = new List<string>();
public static void Main()
{
Console.Title = "Client";
ConnectLoop();
//Task.WaitAll(sendTask, recieveTask); //wait for end of all tasks
}
private static void ConnectLoop()
{
bool refreshTask = false;
Task sendTask = null, recieveTask = null, updateConvTask = null;
while (true)
{
if(!client.Connected) //try to connect
{
refreshTask = true;
if(sendTask != null || recieveTask != null || updateConvTask != null)
{
sendTask.Dispose();
recieveTask.Dispose();
updateConvTask.Dispose();
sendTask = recieveTask = updateConvTask = null;
}
Console.WriteLine("Connecting to server...");
try
{
client.Connect(IPAddress.Parse("127.0.0.1"), 8080);
}
catch (SocketException) { }
Thread.Sleep(10);
}
else if(refreshTask) // \/ CONNECTED \/
{
Console.WriteLine("Connected.");
reader = new StreamReader(client.GetStream());
writer = new StreamWriter(client.GetStream());
sendTask = Task.Run(() => SendMessage()); //task for sending messages
recieveTask = Task.Run(() => RecieveMessage()); //task for recieving messages
updateConvTask = Task.Run(() => UpdateConversation()); //task for update console window
refreshTask = false;
}
}
}
private static void SendMessage()
{
string msgToSend = string.Empty;
do
{
Console.WriteLine("Enter a message to send to the server");
msgToSend = Console.ReadLine();
writer.WriteLine(msgToSend);
writer.Flush();
} while (!msgToSend.Equals("Exit"));
EndConnection();
}
private static void RecieveMessage()
{
try
{
while (client.Connected)
{
//Console.Clear();
string msg = reader.ReadLine();
if(msg != string.Empty)
{
if (msg == "%C") //special message from server, clear messages if recieve it
{
messages.Clear();
}
else
{
messages.Add(msg);
refresh = true; //refresh console window
}
}
//Console.Clear();
//Console.WriteLine(msgFromServer);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
}
private static void UpdateConversation()
{
//string conversationTmp = string.Empty;
try
{
while (true)
{
if (refresh) //only if refresh
{
refresh = false;
Console.Clear();
messages.ForEach(msg => Console.WriteLine(msg)); //write all messages
Console.WriteLine();
}
}
}
catch (Exception) { }
}
private static void EndConnection()
{
reader.Close();
writer.Close();
client.Close();
}
}
}
I know that my bug will be something stupid. I'm new to TCP/IP applications, could you give me links to some tutorials that use it and Tasks?
Thanks for any help.
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());
}
}
Hello Could anybody help me about this I'm trying to create client and server application reverse connection. When I tried to open the client and server I didn't encounter any problem vise versa. The scenario is I execute the client and the server but when I closed the server and re open again it doesn't accept any connection both connection lost.
Here is the Code:
CLIENT CODE:
namespace client1
{
class Program
{
public static bool isConnected { get; set; }
public static NetworkStream Writer { get; set; }
public static NetworkStream Reciever { get; set; }
static void Main(string[] args)
{
Connect_To_Server();
}
public static void Connect_To_Server()
{
TcpClient Connecting = new TcpClient();
string IP = "178.121.1.2";
while (isConnected == false)
{
try
{
Connecting.Connect(IP, 2000);
isConnected = true;
Writer = Connecting.GetStream();
Reciever = Connecting.GetStream();
Console.WriteLine("Connected: " + IP);
}
catch
{
Console.WriteLine("Error Connection... .");
Console.Clear();
}
}
Console.ReadKey();
}
}
}
SERVER CODE:
namespace server1
{
class Program
{
public static bool isConnected { get; set; }
public static NetworkStream Writer { get; set; }
static void Main(string[] args)
{
Listen_To_Client();
}
public static void Listen_To_Client()
{
TcpListener Listen = new TcpListener(2000);
while (true)
{
Listen.Start();
if (Listen.Pending())
{
TcpClient Connect = Listen.AcceptTcpClient();
isConnected = true;
Console.WriteLine("Connection Accepted");
Writer = Connect.GetStream();
Console.ReadKey();
}
}
}
}
}
Instead of using a local variable isConnected you should check for Connecting.Connected.
In your case you connect once and set isConnected to true. Now your while loop condition ends up as false and you never try to reconnect your client.
Edit:
while (true)
{
try
{
TcpClient client = new TcpClient(ip, port);
if (client.Connected)
{
// do something
client.close();
}
}
catch (SocketException) { }
Thread.Sleep(millisecs);
}
Bare in mind that you should not run this loop in your GUI thread since it has all sorts of blocking potential. Also only try to connect if you want to interact with the server. But for now this code should work for you.
What's the most simple way that a WCF Service, that's being hosted by a console application , can interact with the said console application, to do a Console.WriteLine() ie.
Some code:
The contract:
[ServiceContract(Name = "IProdsService")]
public interface IProdsService
{
[OperationContract(Name = "Alert",IsOneWay=true)]
void Alert(string msg);
}
The Service:
public class ProdsService : IProdsService
{
//IProdsService.Alert implementation
public void Alert(string msg)
{
//TODO: Send Alert to Console Application!
}
}
The Console App:
class Program
{
static void Main(string[] args)
{
ServiceHost prodService = new ServiceHost(typeof(ProdsService));
ServiceDescription serviceDesciption = prodService.Description;
prodService.Open();
Console.ReadLine();
}
}
Following is an example of running host and client where host can log message on the console. On your example, I am not sure why you have set IsOneWay=true. For this specific case, one way is not what you want. Also, I have used net.tcp binding in the following example; it should work with any other binding as well.
Basically in the example, user's entry is sent to the host service which echos the message on the console.
[ServiceContract]
public interface IProdsService
{
[OperationContract]
void Alert(string msg);
}
/// <summary>
/// Host Class
/// </summary>
public class ProdsService : IProdsService
{
public ProdsService()
{
Console.WriteLine("Service instantiated.");
}
public void Alert(string msg)
{
Console.WriteLine(msg);
}
}
/// <summary>
/// Client proxy wrapper
/// </summary>
public class ProdsServiceClient : ClientBase<IProdsService>, IProdsService
{
public ProdsServiceClient()
{
}
public ProdsServiceClient(System.ServiceModel.Channels.Binding binding, System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}
public void Alert(string msg)
{
base.Channel.Alert(msg);
}
}
class Program
{
static ManualResetEvent _reset;
static void Main(string[] args)
{
string host = "localhost";
int port = 8888;
//ManualResetEvent is used for syncing start/stop of service.
_reset = new ManualResetEvent(false);
var action = new Action<string, int>(Start);
var result = action.BeginInvoke(host, port, null, null);
//Wait for svc startup, this can be synced with resetEvents.
Thread.Sleep(2000);
//Create a client instance and send your messages to host
using (var client = new ProdsServiceClient(new NetTcpBinding(), new EndpointAddress(string.Format("net.tcp://{0}:{1}", host, port))))
{
client.Alert("Test message");
string msg = string.Empty;
do
{
Console.Write("Type a message to send (X to exit): ");
msg = Console.ReadLine();
client.Alert(msg);
}
while (!msg.Trim().ToUpper().Equals("X"));
}
//Signal host to stop
_reset.Set();
action.EndInvoke(result);
Console.Write("Press any to exit.");
Console.ReadKey();
}
static void Start(string host, int port)
{
string uri = string.Format("net.tcp://{0}:{1}", host, port);
//var server = new ProdsService();
ServiceHost prodService = new ServiceHost(typeof(ProdsService));
prodService.AddServiceEndpoint(typeof(IProdsService), new NetTcpBinding(), uri);
Console.WriteLine("Service host opened");
prodService.Open();
//Wait until signaled to stop
_reset.WaitOne();
Console.WriteLine("Stopping host, please wait...");
prodService.Close();
Console.WriteLine("Service host closed");
}
}
duh, my bad, just calling console.writeline from the alert operation does it, i was being fooled by the oneway and was not getting an error...so that's no more oneways for me...