2017-04-10 70 views
1

我想用我的机器人网络套接字与服务器通信。但是在运行时它会抛出System.NullReferenceException异常。我在不同的线程中运行套接字,以便它不会干扰机器人。套接字,空引用异常

我正在使用WebsocketSharp库。

第一条消息进来很好,但第二条消息在HumanCollaboratorDialog类的以下行中引发异常。

await context.PostAsync(e.Data); 

我的Socket流类是如下:

public static class SocketStream 
{ 
    public static WebSocket ws; 
    private static List<string> serverMsg = new List<string>(); 

    public static void initializeSocket() 
    { 

     ws = new WebSocket("ws://Some IP:8080/human-collaborator/data"); 
     Debug.WriteLine("****** INITIALIZED SOCKET (should happen only once) *****"); 
     Task.Run(() => startSocketStream()); 

    } 

    private static void startSocketStream() 
    { 
     int attempts = 0; 
     while (!ws.IsAlive) 
     { 
      try 
      { 
       attempts++; 
       ws.Connect(); 
      } 
      catch (WebSocketException) 
      { 

       Debug.WriteLine("Connection attempts: " + attempts.ToString()); 
      } 

     } 

     ws.OnOpen += (sender, args) => 
     { 
      Debug.WriteLine("# SOCKET OPENED"); 

     }; 

     ws.OnError += (sender, args) => 
     { 
      Debug.WriteLine("# SOME ERROR OCCURED"); 
     }; 

     ws.OnClose += (sender, args) => 
     { 
      Debug.WriteLine("# SOCKET CLOSED"); 

     }; 
    } 
} 

我打电话Global.asx的initializeSocket()方法的应用水平

public class WebApiApplication : System.Web.HttpApplication 
{ 
    protected void Application_Start() 
    { 
     GlobalConfiguration.Configure(WebApiConfig.Register); 
     SocketStream.initializeSocket(); 

    } 
} 

我HumanCollaboratorDialog类中运行如下:

[Serializable] 
public class HumanCollaboratorDialog : IDialog<object> 
{ 

    public async Task StartAsync(IDialogContext context) 
    { 

     context.Wait(this.MessageReceivedAsync); 

    } 

    private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result) 
    { 

     var message = await result; 

     SocketStream.ws.OnMessage += async (sender, e) => 
     { 
      try 
      { 
       await context.PostAsync(e.Data); 
      } 
      catch (HttpRequestException ex) 
      { 
       throw ex; 
      } 
     }; 

      Thread.Sleep(500); 
      string output = message.Text; 
      SocketStream.ws.Send(output); 
      Thread.Sleep(500); 

     context.Wait(MessageReceivedAsync); 

    } 
} 

我MessagesController有以下POST方法:

public virtual async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
    { 
     if (activity.Type == ActivityTypes.Message) 
     { 
      await Conversation.SendAsync(activity,() => new HumanCollaboratorDialog()); 
     } 
     else 
     { 
      HandleSystemMessage(activity); 
     } 
     var response = Request.CreateResponse(HttpStatusCode.OK); 
     return response; 
    } 

Neithet e.Data也不环境是空的。我认为问题是与套接字连接或可能是我在做SocketStream类中的错误。以下是图像

Exception-Image enter image description here

+0

我不知道你为什么在Web API中运行套接字... –

+0

@EzequielJadib我想在后台连续运行套接字,以便在服务器上发生某些变化时它可以通知机器人。在这种情况下更好的解决方案是什么? –

+2

在旁注中,不要做'catch(Exception ex){throw ex; }'。 [它是邪恶的](http://stackoverflow.com/questions/881473/why-catch-and-rethrow-an-exception-in-c) – Default

回答

1

你的机器人是一个Web服务。消息由客户端(网页,应用程序,其他服务等)发送到服务,并在MessagesController的Post方法中接收。您无需在服务器上安装套接字代码,以查看您正在尝试执行的操作。网络套接字可用于通过直接线路连接从机器人接收客户端上的消息。


下面是使用Bot Framework的Direct Line Client和创建Web套接字连接的示例。请注意如何在网络插座是从对话的StreamUrl创建:

DirectLineClientCredentials creds = new DirectLineClientCredentials(directLineSecret); 
DirectLineClient directLineClient = new DirectLineClient(creds); 
Conversation conversation = await directLineClient.Conversations.StartConversationAsync(); 

using (var webSocketClient = new WebSocket(conversation.StreamUrl)) 
{ 
    webSocketClient.OnMessage += WebSocketClient_OnMessage; 
    webSocketClient.Connect(); 
    while (true) 

    { 
     string input = Console.ReadLine().Trim(); 

     if (input.ToLower() == "exit") 
     { 
      break; 
     } 
     else 
     { 
      if (input.Length > 0) 
      { 
       Activity userMessage = new Activity 
       { 
        From = new ChannelAccount(fromUser), 
        Text = input, 
        Type = ActivityTypes.Message 
       }; 

       await directLineClient.Conversations.PostActivityAsync(conversation.ConversationId, userMessage); 
      } 
     } 
    } 
} 
private static void WebSocketClient_OnMessage(object sender, MessageEventArgs e) 
{ 
    // avoid null reference exception when no data received 
    if (string.IsNullOrWhiteSpace(e.Data)) 
    { 
     return; 
    } 

    var activitySet = JsonConvert.DeserializeObject<ActivitySet>(e.Data); 
    var activities = from x in activitySet.Activities 
         where x.From.Id == botId 
         select x; 

    foreach (Activity activity in activities) 
    { 
     Console.WriteLine(activity.Text); 
    } 
} 

这是从使用直通线与机器人通信的控制台应用程序,在这里使用的网络套接字上监听消息: https://github.com/Microsoft/BotBuilder-Samples/tree/master/CSharp/core-DirectLineWebSockets