使用新的信号R为DotNet核心从控制台应用程序发送消息应用程序到网页

问题描述:

我使用https://blogs.msdn.microsoft.com/webdev/2017/09/14/announcing-signalr-for-asp-net-core-2-0/这个示例来创建一个控制台应用程序,可以从简单的控制台应用程序发送消息到网页。使用新的信号R为DotNet核心从控制台应用程序发送消息应用程序到网页

下面是控制台应用程序的一个简单示例,它读取用户输入并在屏幕上打印输入,我想将相同的用户输入也发送到网页。

static void Main(string[] args) 
     { 
      while (true) 
      { 
       Console.WriteLine("Enter input:"); 
       string line = Console.ReadLine(); 
       if (line == "exit") 
       { 
        break; 
       } 
       sendSignalToClient(line); 
       Console.Write("Message Sent To Client: " + line); 
      } 
     } 

     private static void sendSignalToClient(string line) 
     { 
      //Send a message from this app to web client using signalR 
     } 

我刚刚开始了解这一点。任何与此相关的材料或建议表示赞赏。 - 谢谢

编辑:我正在使用示例signalR聊天应用程序。

public class Program 
    { 
     public static void Main(string[] args) 
     { 
      BuildWebHost(args).Run(); 
     } 

     public static IWebHost BuildWebHost(string[] args) => 
      WebHost.CreateDefaultBuilder(args) 
       .UseStartup<Startup>() 
       .Build(); 
    } 

public class ChatHub : Hub 
    { 
     public void Send(string name, string message) 
     { 
      // Call the broadcastMessage method to update clients. 
      Clients.All.InvokeAsync("broadcastMessage", name, message); 
     } 
    } 

public class Startup 
    { 
     public void ConfigureServices(IServiceCollection services) 
     { 
      services.AddSignalR(); 
     } 

     public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
     { 
      if (env.IsDevelopment()) 
      { 
       app.UseDeveloperExceptionPage(); 
      } 
      app.UseFileServer(); 

      app.UseSignalR(routes => 
      { 
       routes.MapHub<ChatHub>("chat"); 
      }); 
     } 

下面是是将消息发送到网页控制台应用程序的代码

class Program : Hub 
{ 
    static void Main(string[] args) 
    { 
     Task.Run(Run).Wait(); 
    } 

    static async Task Run() 
    { 
     var connection = new HubConnectionBuilder() 
      .WithUrl("http://localhost:59768/chat") 
      .WithConsoleLogger() 
      .WithMessagePackProtocol() 
      .WithTransport(TransportType.WebSockets) 
      .Build(); 

     await connection.StartAsync(); 

     Console.WriteLine("Starting connection. Press Ctrl-C to close."); 
     var cts = new CancellationTokenSource(); 
     Console.CancelKeyPress += (sender, a) => 
     { 
      a.Cancel = true; 
      cts.Cancel(); 
     }; 

     connection.Closed += e => 
     { 
      Console.WriteLine("Connection closed with error: {0}", e); 

      cts.Cancel(); 
      return Task.CompletedTask; 
     }; 

     connection.On("broadcastMessage", async() => 
     { 


     }); 

     while (true) 
     { 
      Thread.Sleep(2000); 

      await connection.SendAsync("send", "alex", "hello"); 

     } 
    } 

所有的代码是工作,但在控制台应用程序我收到此异常:

Microsoft.AspNetCore.Sockets.Client.HttpConnection[19] 
     09/17/2017 13:47:17: Connection Id 40da6d4b-9c47-4831-802f-628bbb172e10: An exception was thrown from the 'Received' event handler. 
System.FormatException: Target method expects 0 arguments(s) but invocation has 2 argument(s). 
    at Microsoft.AspNetCore.SignalR.Internal.Protocol.MessagePackHubProtocol.CreateInvocationMessage(Unpacker unpacker, IInvocationBinder binder) 
    at Microsoft.AspNetCore.SignalR.Internal.Protocol.MessagePackHubProtocol.TryParseMessages(ReadOnlyBuffer`1 input, IInvocationBinder binder, IList`1& messages) 
    at Microsoft.AspNetCore.SignalR.Internal.HubProtocolReaderWriter.ReadMessages(Byte[] input, IInvocationBinder binder, IList`1& messages) 
    at Microsoft.AspNetCore.SignalR.Client.HubConnection.<OnDataReceivedAsync>d__31.MoveNext() 
--- End of stack trace from previous location where exception was thrown --- 
    at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() 
    at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
    at Microsoft.AspNetCore.Sockets.Client.HttpConnection.<>c__DisplayClass49_0.<<ReceiveAsync>b__0>d.MoveNext() 

看看这个教程,因为虽然它有点老,它会给你很好的建议:

https://docs.microsoft.com/en-us/aspnet/signalr/overview/getting-started/tutorial-getting-started-with-signalr

一方面,您的网页需要连接到SignalR Hub,另一方面您的控制台应该连接到服务,可能在您的Web项目中,将消息发送到集线器并从那里到所有注册客户。关键是中枢在客户端执行JavaScript函数,但由于注册,它必须知道客户端,并且必须调用中心实例来执行方法。使我感觉到的是将集线器注入API控制器,并使用httpclient将输入发布到控制器。

另一个很好的教程,但是这一次是最近的:

https://spontifixus.github.io/ASPNET-Core-SignalR-with-Aurelia-and-Webpack/

我希望它能帮助。

胡安

编辑:

我刚刚找到了答案(可能2017年),以同样的问题在这里:

SignalR Console app example

在服务器端:

[HubName("MyHub")] 
     public class MyHub : Hub 
     { 
      public void Send(string name, string message) 
      { 
       Clients.All.addMessage(name, message); 
      } 
     } 

并在客户端:

var myHub = connection.CreateHubProxy("MyHub"); 
... 
// To write received messages: 
myHub.On<string, string>("addMessage", (s1, s2) => { 
         Console.WriteLine(s1 + ": " + s2); 
        }); 
... 
// To send messages: 
myHub.Invoke<string>("Send", name, message).ContinueWith(task1 => { 
          if (task1.IsFaulted) 
          { 
           Console.WriteLine("There was an error calling send: {0}", task1.Exception.GetBaseException()); 
          } 
          else 
          { 
           Console.WriteLine(task1.Result); 
          } 
         }); 

这可能也适用于你亚历山大。

我希望它有帮助。

胡安

+0

谢谢,我是能够发送消息的控制台应用程序,但我也越来越例外。 – Alexander

+0

我会尽量帮助使用笔记本电脑,这只是一个手机复杂的东西......大声笑...但是,根据异常消息有一些参数有问题,我真的不知道是否问题是客户端或服务器端。我会在几个小时内看看它。答应了。 – Juan

+0

好的,但例外情况来自客户端。 – Alexander

事件处理程序应该有一个字符串参数,它应该是这样的:

connection.On<string>("broadcastMessage", data => 
{ 

});