websocket.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. use actors::ws::WebsocketActor;
  2. use actors::{Actor, ActorHandle};
  3. use std::collections::HashMap;
  4. use std::sync::atomic::AtomicUsize;
  5. use std::sync::{Arc, RwLock};
  6. use warp::Filter;
  7. type Arbiter = Arc<RwLock<HashMap<usize, ActorHandle<WebsocketActor>>>>;
  8. static ID: AtomicUsize = AtomicUsize::new(0);
  9. #[tokio::main]
  10. async fn main() {
  11. let pool = Arc::new(RwLock::new(HashMap::new()));
  12. let pool = warp::any().map(move || pool.clone());
  13. // GET /chat -> websocket upgrade
  14. let chat = warp::path("chat")
  15. // The `ws()` filter will prepare Websocket handshake...
  16. .and(warp::ws())
  17. .and(pool)
  18. .map(|ws: warp::ws::Ws, pool: Arbiter| {
  19. // This will call our function if the handshake succeeds.
  20. ws.on_upgrade(move |socket| {
  21. let actor = WebsocketActor::new(socket);
  22. let handle = actor.start();
  23. // let id = ID.fetch_add(1, std::sync::atomic::Ordering::Relaxed);
  24. // println!("Adding actor {id}");
  25. pool.write().unwrap().insert(0, handle);
  26. futures::future::ready(())
  27. })
  28. });
  29. // GET / -> index html
  30. let index = warp::path::end().map(|| warp::reply::html(INDEX_HTML));
  31. let routes = index.or(chat);
  32. warp::serve(routes).run(([127, 0, 0, 1], 3030)).await
  33. }
  34. static INDEX_HTML: &str = r#"<!DOCTYPE html>
  35. <html lang="en">
  36. <head>
  37. <title>Warp Chat</title>
  38. </head>
  39. <body>
  40. <h1>Warp chat</h1>
  41. <div id="chat">
  42. <p><em>Connecting...</em></p>
  43. </div>
  44. <input type="text" id="text" />
  45. <button type="button" id="send">Send</button>
  46. <script type="text/javascript">
  47. const chat = document.getElementById('chat');
  48. const text = document.getElementById('text');
  49. const uri = 'ws://' + location.host + '/chat';
  50. const ws = new WebSocket(uri);
  51. let num = 0;
  52. function message(data) {
  53. if (num % 10000 === 0) chat.innerHTML = `${num}`
  54. }
  55. ws.onopen = function() {
  56. chat.innerHTML = '<p><em>Connected!</em></p>';
  57. };
  58. ws.onmessage = function(msg) {
  59. message(msg.data);
  60. num += 1;
  61. };
  62. ws.onclose = function() {
  63. chat.getElementsByTagName('em')[0].innerText = 'Disconnected!';
  64. };
  65. send.onclick = function() {
  66. const msg = text.value;
  67. let i = 0;
  68. while (i < 100000) {
  69. ws.send(msg);
  70. i += 1;
  71. }
  72. text.value = '';
  73. message('<You>: ' + msg);
  74. };
  75. </script>
  76. </body>
  77. </html>
  78. "#;