App.razor 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. @inject HttpClient http
  2. @code {
  3. private string nickName;
  4. private string nickNameClass => string.IsNullOrWhiteSpace(nickName) ? "border-warning border-4 form-control" : "form-control";
  5. private string message;
  6. private string messageClass => string.IsNullOrWhiteSpace(message) ? "border-warning border-4 form-control" : "form-control";
  7. private int connState = 0;
  8. private const int maxDisplayMessage = 1000;
  9. private List<string> displayingMessages = new List<string>(maxDisplayMessage);
  10. }
  11. <h2>Simple Web Chat</h2>
  12. @if (connState == 0)
  13. {
  14. <div class="input-group mb-3">
  15. <InputText class="@nickNameClass" placeholder="Nick name" type="search" onsearch="@Connect" @oninput="NickNameChanged" ValueExpression="()=>nickName"></InputText>
  16. <button @onclick="@Connect" class="btn btn-outline-secondary" type="button">Connect</button>
  17. </div>
  18. }
  19. else if (connState == 1)
  20. {
  21. <span>Conecting...</span>
  22. }
  23. else if (connState == 2)
  24. {
  25. <div class="input-group mb-3">
  26. <InputText class="@messageClass" placeholder="Message to send" type="search" onsearch="@Send" @oninput="MessageChanged" Value="@message" ValueExpression="()=>message"></InputText>
  27. <button @onclick="@Send" class="btn btn-outline-secondary" type="button">Send</button>
  28. </div>
  29. @foreach (var item in displayingMessages)
  30. {
  31. <pre class="font-monospace" style="white-space:pre-wrap">@item</pre>
  32. }
  33. }
  34. else
  35. {
  36. <span>Error</span>
  37. }
  38. @code {
  39. private System.Net.WebSockets.ClientWebSocket sck;
  40. private void NickNameChanged(ChangeEventArgs e)
  41. {
  42. nickName = e.Value.ToString().Trim();
  43. StateHasChanged();
  44. }
  45. private void MessageChanged(ChangeEventArgs e)
  46. {
  47. message = e.Value.ToString().Trim();
  48. StateHasChanged();
  49. }
  50. private async Task Connect()
  51. {
  52. if (string.IsNullOrEmpty(nickName)) return;
  53. connState = 1;
  54. StateHasChanged();
  55. try
  56. {
  57. sck = new System.Net.WebSockets.ClientWebSocket();
  58. sck.Options.AddSubProtocol("swcp");
  59. var b = http.BaseAddress;
  60. await sck.ConnectAsync(new Uri($"{(b.Scheme == "https" ? "wss" : "ws")}://{b.Host}:{b.Port}/connect"), default);
  61. connState = 2;
  62. StateHasChanged();
  63. var buf = System.Text.Encoding.UTF8.GetBytes(nickName);
  64. await sck.SendAsync(buf, System.Net.WebSockets.WebSocketMessageType.Text, true, default);
  65. while (true)
  66. {
  67. buf = new Byte[1024];
  68. var r = await sck.ReceiveAsync(buf, default);
  69. displayingMessages.Insert(0, System.Text.Encoding.UTF8.GetString(buf, 0, r.Count));
  70. while (displayingMessages.Count >= maxDisplayMessage) displayingMessages.RemoveAt(maxDisplayMessage - 1);
  71. StateHasChanged();
  72. }
  73. }
  74. catch (Exception)
  75. {
  76. connState = -1;
  77. }
  78. }
  79. private async Task Send()
  80. {
  81. if (string.IsNullOrEmpty(message)) return;
  82. var msg = $"{nickName}: {message}";
  83. await sck.SendAsync(System.Text.Encoding.UTF8.GetBytes(msg), System.Net.WebSockets.WebSocketMessageType.Text, true, default);
  84. message = "";
  85. StateHasChanged();
  86. }
  87. }