websocket-server-2pass.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /**
  2. * Copyright FunASR (https://github.com/alibaba-damo-academy/FunASR). All Rights
  3. * Reserved. MIT License (https://opensource.org/licenses/MIT)
  4. */
  5. /* 2022-2023 by zhaomingwork */
  6. // websocket server for asr engine
  7. // take some ideas from https://github.com/k2-fsa/sherpa-onnx
  8. // online-websocket-server-impl.cc, thanks. The websocket server has two threads
  9. // pools, one for handle network data and one for asr decoder.
  10. // now only support offline engine.
  11. #ifndef WEBSOCKET_SERVER_H_
  12. #define WEBSOCKET_SERVER_H_
  13. #include <iostream>
  14. #include <map>
  15. #include <memory>
  16. #include <string>
  17. #include <thread>
  18. #include <utility>
  19. #define ASIO_STANDALONE 1 // not boost
  20. #include <glog/logging.h>
  21. #include "util/text-utils.h"
  22. #include <fstream>
  23. #include <functional>
  24. #include <websocketpp/common/thread.hpp>
  25. #include <websocketpp/config/asio.hpp>
  26. #include <websocketpp/server.hpp>
  27. #include "asio.hpp"
  28. #include "com-define.h"
  29. #include "funasrruntime.h"
  30. #include "nlohmann/json.hpp"
  31. #include "tclap/CmdLine.h"
  32. typedef websocketpp::server<websocketpp::config::asio> server;
  33. typedef websocketpp::server<websocketpp::config::asio_tls> wss_server;
  34. typedef server::message_ptr message_ptr;
  35. using websocketpp::lib::bind;
  36. using websocketpp::lib::placeholders::_1;
  37. using websocketpp::lib::placeholders::_2;
  38. typedef websocketpp::lib::lock_guard<websocketpp::lib::mutex> scoped_lock;
  39. typedef websocketpp::lib::unique_lock<websocketpp::lib::mutex> unique_lock;
  40. typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context>
  41. context_ptr;
  42. typedef struct {
  43. std::string msg;
  44. float snippet_time;
  45. } FUNASR_RECOG_RESULT;
  46. typedef struct {
  47. nlohmann::json msg;
  48. std::shared_ptr<std::vector<char>> samples;
  49. std::shared_ptr<std::vector<std::vector<std::string>>> punc_cache;
  50. std::shared_ptr<std::vector<std::vector<float>>> hotwords_embedding=nullptr;
  51. std::shared_ptr<websocketpp::lib::mutex> thread_lock; // lock for each connection
  52. FUNASR_HANDLE tpass_online_handle=nullptr;
  53. std::string online_res = "";
  54. std::string tpass_res = "";
  55. std::shared_ptr<asio::io_context::strand> strand_; // for data execute in order
  56. FUNASR_DEC_HANDLE decoder_handle=nullptr;
  57. } FUNASR_MESSAGE;
  58. // See https://wiki.mozilla.org/Security/Server_Side_TLS for more details about
  59. // the TLS modes. The code below demonstrates how to implement both the modern
  60. enum tls_mode { MOZILLA_INTERMEDIATE = 1, MOZILLA_MODERN = 2 };
  61. class WebSocketServer {
  62. public:
  63. WebSocketServer(asio::io_context& io_decoder, bool is_ssl, server* server,
  64. wss_server* wss_server, std::string& s_certfile,
  65. std::string& s_keyfile)
  66. : io_decoder_(io_decoder),
  67. is_ssl(is_ssl),
  68. server_(server),
  69. wss_server_(wss_server) {
  70. if (is_ssl) {
  71. std::cout << "certfile path is " << s_certfile << std::endl;
  72. wss_server->set_tls_init_handler(
  73. bind<context_ptr>(&WebSocketServer::on_tls_init, this,
  74. MOZILLA_INTERMEDIATE, ::_1, s_certfile, s_keyfile));
  75. wss_server_->set_message_handler(
  76. [this](websocketpp::connection_hdl hdl, message_ptr msg) {
  77. on_message(hdl, msg);
  78. });
  79. // set open handle
  80. wss_server_->set_open_handler(
  81. [this](websocketpp::connection_hdl hdl) { on_open(hdl); });
  82. // set close handle
  83. wss_server_->set_close_handler(
  84. [this](websocketpp::connection_hdl hdl) { on_close(hdl); });
  85. // begin accept
  86. wss_server_->start_accept();
  87. // not print log
  88. wss_server_->clear_access_channels(websocketpp::log::alevel::all);
  89. } else {
  90. // set message handle
  91. server_->set_message_handler(
  92. [this](websocketpp::connection_hdl hdl, message_ptr msg) {
  93. on_message(hdl, msg);
  94. });
  95. // set open handle
  96. server_->set_open_handler(
  97. [this](websocketpp::connection_hdl hdl) { on_open(hdl); });
  98. // set close handle
  99. server_->set_close_handler(
  100. [this](websocketpp::connection_hdl hdl) { on_close(hdl); });
  101. // begin accept
  102. server_->start_accept();
  103. // not print log
  104. server_->clear_access_channels(websocketpp::log::alevel::all);
  105. }
  106. }
  107. void do_decoder(std::vector<char>& buffer, websocketpp::connection_hdl& hdl,
  108. nlohmann::json& msg,
  109. std::vector<std::vector<std::string>>& punc_cache,
  110. std::vector<std::vector<float>> &hotwords_embedding,
  111. websocketpp::lib::mutex& thread_lock, bool& is_final,
  112. std::string wav_name,
  113. std::string modetype,
  114. bool itn,
  115. int audio_fs,
  116. std::string wav_format,
  117. FUNASR_HANDLE& tpass_online_handle,
  118. FUNASR_DEC_HANDLE& decoder_handle);
  119. void initAsr(std::map<std::string, std::string>& model_path, int thread_num);
  120. void on_message(websocketpp::connection_hdl hdl, message_ptr msg);
  121. void on_open(websocketpp::connection_hdl hdl);
  122. void on_close(websocketpp::connection_hdl hdl);
  123. context_ptr on_tls_init(tls_mode mode, websocketpp::connection_hdl hdl,
  124. std::string& s_certfile, std::string& s_keyfile);
  125. private:
  126. void check_and_clean_connection();
  127. asio::io_context& io_decoder_; // threads for asr decoder
  128. // std::ofstream fout;
  129. // FUNASR_HANDLE asr_handle; // asr engine handle
  130. FUNASR_HANDLE tpass_handle=nullptr;
  131. bool isonline = true; // online or offline engine, now only support offline
  132. bool is_ssl = true;
  133. server* server_; // websocket server
  134. wss_server* wss_server_; // websocket server
  135. // use map to keep the received samples data from one connection in offline
  136. // engine. if for online engline, a data struct is needed(TODO)
  137. std::map<websocketpp::connection_hdl, std::shared_ptr<FUNASR_MESSAGE>,
  138. std::owner_less<websocketpp::connection_hdl>>
  139. data_map;
  140. websocketpp::lib::mutex m_lock; // mutex for sample_map
  141. };
  142. #endif // WEBSOCKET_SERVER_H_