2017-04-10 66 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