diff options
Diffstat (limited to 'graphics/asymptote/LspCpp/examples/WebsocketExample.cpp')
-rw-r--r-- | graphics/asymptote/LspCpp/examples/WebsocketExample.cpp | 592 |
1 files changed, 296 insertions, 296 deletions
diff --git a/graphics/asymptote/LspCpp/examples/WebsocketExample.cpp b/graphics/asymptote/LspCpp/examples/WebsocketExample.cpp index d79569f536..40d920ac00 100644 --- a/graphics/asymptote/LspCpp/examples/WebsocketExample.cpp +++ b/graphics/asymptote/LspCpp/examples/WebsocketExample.cpp @@ -1,296 +1,296 @@ -
-#include "LibLsp/JsonRpc/WebSocketServer.h"
-#include "LibLsp/lsp/textDocument/signature_help.h"
-#include "LibLsp/lsp/general/initialize.h"
-#include "LibLsp/lsp/ProtocolJsonHandler.h"
-#include "LibLsp/lsp/textDocument/typeHierarchy.h"
-#include "LibLsp/lsp/AbsolutePath.h"
-#include "LibLsp/lsp/textDocument/resolveCompletionItem.h"
-#include <network/uri.hpp>
-
-
-#include "LibLsp/JsonRpc/Endpoint.h"
-#include "LibLsp/JsonRpc/stream.h"
-#include "LibLsp/JsonRpc/TcpServer.h"
-#include "LibLsp/lsp/textDocument/document_symbol.h"
-#include "LibLsp/lsp/workspace/execute_command.h"
-
-#include <boost/filesystem.hpp>
-#include <boost/asio.hpp>
-#include <iostream>
-#include <boost/beast/core.hpp>
-#include <boost/beast/websocket.hpp>
-#include <boost/asio/dispatch.hpp>
-#include <boost/asio/strand.hpp>
-#include <algorithm>
-#include <cstdlib>
-#include <functional>
-#include <iostream>
-#include <memory>
-#include <string>
-#include <thread>
-#include <vector>
-
-#include <boost/beast/version.hpp>
-#include <boost/beast/websocket.hpp>
-#include <boost/asio/dispatch.hpp>
-#include "LibLsp/JsonRpc/Endpoint.h"
-#include "LibLsp/JsonRpc/RemoteEndPoint.h"
-#include "LibLsp/JsonRpc/stream.h"
-#include "LibLsp/lsp/ProtocolJsonHandler.h"
-
-namespace beast = boost::beast; // from <boost/beast.hpp>
-namespace http = beast::http; // from <boost/beast/http.hpp>
-namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp>
-namespace net = boost::asio; // from <boost/asio.hpp>
-using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp>
-
-//------------------------------------------------------------------------------
-
-std::string _address = "127.0.0.1";
-std::string _port = "9333";
-
-
-
-
-using namespace std;
-class DummyLog :public lsp::Log
-{
-public:
-
- void log(Level level, std::wstring&& msg)
- {
- std::wcout << msg << std::endl;
- };
- void log(Level level, const std::wstring& msg)
- {
- std::wcout << msg << std::endl;
- };
- void log(Level level, std::string&& msg)
- {
- std::cout << msg << std::endl;
- };
- void log(Level level, const std::string& msg)
- {
- std::cout << msg << std::endl;
- };
-};
-
-
-
-// Sends a WebSocket message and prints the response
-class Client : public std::enable_shared_from_this<Client>
-{
- net::io_context ioc;
- tcp::resolver resolver_;
- websocket::stream<beast::tcp_stream> ws_;
- beast::flat_buffer buffer_;
- std::string host_;
- std::string user_agent_;
- std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared< lsp::ProtocolJsonHandler>();
- DummyLog _log;
-
- std::shared_ptr<GenericEndpoint> endpoint = std::make_shared<GenericEndpoint>(_log);
-
- std::shared_ptr<lsp::websocket_stream_wrapper> proxy_;
-public:
- RemoteEndPoint point;
-
-public:
- // Resolver and socket require an io_context
- explicit
- Client()
- : resolver_(net::make_strand(ioc))
- , ws_(net::make_strand(ioc)),point(protocol_json_handler, endpoint, _log)
- {
- proxy_ = std::make_shared<lsp::websocket_stream_wrapper>(ws_);
-
- }
-
- // Start the asynchronous operation
- void
- run(
- char const* host,
- char const* port, char const* user_agent)
- {
- // Save these for later
- host_ = host;
- user_agent_ = user_agent;
- // Look up the domain name
- resolver_.async_resolve(
- host,
- port,
- beast::bind_front_handler(
- &Client::on_resolve,
- shared_from_this()));
- std::thread([&]
- {
- ioc.run();
- }).detach();
- while (!point.IsWorking())
- {
- std::this_thread::sleep_for(std::chrono::milliseconds (50));
- }
- }
-
- void
- on_resolve(
- beast::error_code ec,
- tcp::resolver::results_type results)
- {
- if (ec)
- return;
-
- // Set the timeout for the operation
- beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30));
-
- // Make the connection on the IP address we get from a lookup
- beast::get_lowest_layer(ws_).async_connect(
- results,
- beast::bind_front_handler(
- &Client::on_connect,
- shared_from_this()));
- }
-
- void
- on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type)
- {
- if (ec)
- return;
-
- // Turn off the timeout on the tcp_stream, because
- // the websocket stream has its own timeout system.
- beast::get_lowest_layer(ws_).expires_never();
-
- // Set suggested timeout settings for the websocket
- ws_.set_option(
- websocket::stream_base::timeout::suggested(
- beast::role_type::client));
-
- // Set a decorator to change the User-Agent of the handshake
- ws_.set_option(websocket::stream_base::decorator(
- [=](websocket::request_type& req)
- {
- req.set(http::field::user_agent,
- user_agent_.c_str());
- }));
-
- // Perform the websocket handshake
- ws_.async_handshake(host_, "/",
- beast::bind_front_handler(
- &Client::on_handshake,
- shared_from_this()));
- }
-
- void
- on_handshake(beast::error_code ec)
- {
- if (ec)
- return;
-
- // Send the message
-
-
- point.startProcessingMessages(proxy_, proxy_);
- // Read a message into our buffer
- ws_.async_read(
- buffer_,
- beast::bind_front_handler(
- &Client::on_read,
- shared_from_this()));
- }
-
-
- void
- on_read(
- beast::error_code ec,
- std::size_t bytes_transferred)
- {
- boost::ignore_unused(bytes_transferred);
-
- if (ec)
- return;
-
- char* data = reinterpret_cast<char*>(buffer_.data().data());
- std::vector<char> elements(data, data + bytes_transferred);
- buffer_.clear();
- proxy_->on_request.EnqueueAll(std::move(elements), false);
-
- ws_.async_read(
- buffer_,
- beast::bind_front_handler(
- &Client::on_read,
- shared_from_this()));
- }
-
- void
- on_close(beast::error_code ec)
- {
- if (ec)
- return;
-
- // If we get here then the connection is closed gracefully
-
- // The make_printable() function helps print a ConstBufferSequence
- std::cout << beast::make_printable(buffer_.data()) << std::endl;
- }
-};
-
-class Server
-{
-public:
- Server(const std::string& user_agent) : server(user_agent,_address, _port, protocol_json_handler, endpoint, _log)
- {
- server.point.registerHandler(
- [&](const td_initialize::request& req)
- {
- td_initialize::response rsp;
- CodeLensOptions code_lens_options;
- code_lens_options.resolveProvider = true;
- rsp.result.capabilities.codeLensProvider = code_lens_options;
- return rsp;
- });
- std::thread([&]()
- {
- server.run();
- }).detach();
- }
- ~Server()
- {
- server.stop();
- }
- std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared < lsp::ProtocolJsonHandler >();
- DummyLog _log;
-
- std::shared_ptr < GenericEndpoint > endpoint = std::make_shared<GenericEndpoint>(_log);
- lsp::WebSocketServer server;
-
-};
-
-int main()
-{
- std::string user_agent = std::string(BOOST_BEAST_VERSION_STRING) +" websocket-server-async";
- Server server(user_agent);
-
- auto client = std::make_shared<Client>();
- user_agent = std::string(BOOST_BEAST_VERSION_STRING) + " websocket-client-async";
- client->run(_address.c_str(), _port.c_str(), user_agent.c_str());
-
- td_initialize::request req;
-
- auto rsp = client->point.waitResponse(req);
- if (rsp)
- {
- std::cout << rsp->ToJson() << std::endl;
- }
- return 0;
-}
-
-
-
-
-
-
-
-
-
+ +#include "LibLsp/JsonRpc/WebSocketServer.h" +#include "LibLsp/lsp/textDocument/signature_help.h" +#include "LibLsp/lsp/general/initialize.h" +#include "LibLsp/lsp/ProtocolJsonHandler.h" +#include "LibLsp/lsp/textDocument/typeHierarchy.h" +#include "LibLsp/lsp/AbsolutePath.h" +#include "LibLsp/lsp/textDocument/resolveCompletionItem.h" +#include <network/uri.hpp> + + +#include "LibLsp/JsonRpc/Endpoint.h" +#include "LibLsp/JsonRpc/stream.h" +#include "LibLsp/JsonRpc/TcpServer.h" +#include "LibLsp/lsp/textDocument/document_symbol.h" +#include "LibLsp/lsp/workspace/execute_command.h" + +#include <boost/filesystem.hpp> +#include <boost/asio.hpp> +#include <iostream> +#include <boost/beast/core.hpp> +#include <boost/beast/websocket.hpp> +#include <boost/asio/dispatch.hpp> +#include <boost/asio/strand.hpp> +#include <algorithm> +#include <cstdlib> +#include <functional> +#include <iostream> +#include <memory> +#include <string> +#include <thread> +#include <vector> + +#include <boost/beast/version.hpp> +#include <boost/beast/websocket.hpp> +#include <boost/asio/dispatch.hpp> +#include "LibLsp/JsonRpc/Endpoint.h" +#include "LibLsp/JsonRpc/RemoteEndPoint.h" +#include "LibLsp/JsonRpc/stream.h" +#include "LibLsp/lsp/ProtocolJsonHandler.h" + +namespace beast = boost::beast; // from <boost/beast.hpp> +namespace http = beast::http; // from <boost/beast/http.hpp> +namespace websocket = beast::websocket; // from <boost/beast/websocket.hpp> +namespace net = boost::asio; // from <boost/asio.hpp> +using tcp = boost::asio::ip::tcp; // from <boost/asio/ip/tcp.hpp> + +//------------------------------------------------------------------------------ + +std::string _address = "127.0.0.1"; +std::string _port = "9333"; + + + + +using namespace std; +class DummyLog :public lsp::Log +{ +public: + + void log(Level level, std::wstring&& msg) + { + std::wcout << msg << std::endl; + }; + void log(Level level, const std::wstring& msg) + { + std::wcout << msg << std::endl; + }; + void log(Level level, std::string&& msg) + { + std::cout << msg << std::endl; + }; + void log(Level level, const std::string& msg) + { + std::cout << msg << std::endl; + }; +}; + + + +// Sends a WebSocket message and prints the response +class Client : public std::enable_shared_from_this<Client> +{ + net::io_context ioc; + tcp::resolver resolver_; + websocket::stream<beast::tcp_stream> ws_; + beast::flat_buffer buffer_; + std::string host_; + std::string user_agent_; + std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared< lsp::ProtocolJsonHandler>(); + DummyLog _log; + + std::shared_ptr<GenericEndpoint> endpoint = std::make_shared<GenericEndpoint>(_log); + + std::shared_ptr<lsp::websocket_stream_wrapper> proxy_; +public: + RemoteEndPoint point; + +public: + // Resolver and socket require an io_context + explicit + Client() + : resolver_(net::make_strand(ioc)) + , ws_(net::make_strand(ioc)),point(protocol_json_handler, endpoint, _log) + { + proxy_ = std::make_shared<lsp::websocket_stream_wrapper>(ws_); + + } + + // Start the asynchronous operation + void + run( + char const* host, + char const* port, char const* user_agent) + { + // Save these for later + host_ = host; + user_agent_ = user_agent; + // Look up the domain name + resolver_.async_resolve( + host, + port, + beast::bind_front_handler( + &Client::on_resolve, + shared_from_this())); + std::thread([&] + { + ioc.run(); + }).detach(); + while (!point.IsWorking()) + { + std::this_thread::sleep_for(std::chrono::milliseconds (50)); + } + } + + void + on_resolve( + beast::error_code ec, + tcp::resolver::results_type results) + { + if (ec) + return; + + // Set the timeout for the operation + beast::get_lowest_layer(ws_).expires_after(std::chrono::seconds(30)); + + // Make the connection on the IP address we get from a lookup + beast::get_lowest_layer(ws_).async_connect( + results, + beast::bind_front_handler( + &Client::on_connect, + shared_from_this())); + } + + void + on_connect(beast::error_code ec, tcp::resolver::results_type::endpoint_type) + { + if (ec) + return; + + // Turn off the timeout on the tcp_stream, because + // the websocket stream has its own timeout system. + beast::get_lowest_layer(ws_).expires_never(); + + // Set suggested timeout settings for the websocket + ws_.set_option( + websocket::stream_base::timeout::suggested( + beast::role_type::client)); + + // Set a decorator to change the User-Agent of the handshake + ws_.set_option(websocket::stream_base::decorator( + [=](websocket::request_type& req) + { + req.set(http::field::user_agent, + user_agent_.c_str()); + })); + + // Perform the websocket handshake + ws_.async_handshake(host_, "/", + beast::bind_front_handler( + &Client::on_handshake, + shared_from_this())); + } + + void + on_handshake(beast::error_code ec) + { + if (ec) + return; + + // Send the message + + + point.startProcessingMessages(proxy_, proxy_); + // Read a message into our buffer + ws_.async_read( + buffer_, + beast::bind_front_handler( + &Client::on_read, + shared_from_this())); + } + + + void + on_read( + beast::error_code ec, + std::size_t bytes_transferred) + { + boost::ignore_unused(bytes_transferred); + + if (ec) + return; + + char* data = reinterpret_cast<char*>(buffer_.data().data()); + std::vector<char> elements(data, data + bytes_transferred); + buffer_.clear(); + proxy_->on_request.EnqueueAll(std::move(elements), false); + + ws_.async_read( + buffer_, + beast::bind_front_handler( + &Client::on_read, + shared_from_this())); + } + + void + on_close(beast::error_code ec) + { + if (ec) + return; + + // If we get here then the connection is closed gracefully + + // The make_printable() function helps print a ConstBufferSequence + std::cout << beast::make_printable(buffer_.data()) << std::endl; + } +}; + +class Server +{ +public: + Server(const std::string& user_agent) : server(user_agent,_address, _port, protocol_json_handler, endpoint, _log) + { + server.point.registerHandler( + [&](const td_initialize::request& req) + { + td_initialize::response rsp; + CodeLensOptions code_lens_options; + code_lens_options.resolveProvider = true; + rsp.result.capabilities.codeLensProvider = code_lens_options; + return rsp; + }); + std::thread([&]() + { + server.run(); + }).detach(); + } + ~Server() + { + server.stop(); + } + std::shared_ptr < lsp::ProtocolJsonHandler > protocol_json_handler = std::make_shared < lsp::ProtocolJsonHandler >(); + DummyLog _log; + + std::shared_ptr < GenericEndpoint > endpoint = std::make_shared<GenericEndpoint>(_log); + lsp::WebSocketServer server; + +}; + +int main() +{ + std::string user_agent = std::string(BOOST_BEAST_VERSION_STRING) +" websocket-server-async"; + Server server(user_agent); + + auto client = std::make_shared<Client>(); + user_agent = std::string(BOOST_BEAST_VERSION_STRING) + " websocket-client-async"; + client->run(_address.c_str(), _port.c_str(), user_agent.c_str()); + + td_initialize::request req; + + auto rsp = client->point.waitResponse(req); + if (rsp) + { + std::cout << rsp->ToJson() << std::endl; + } + return 0; +} + + + + + + + + + |