forked from boostorg/beast
		
	
		
			
	
	
		
			110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Copyright (c) 2016-2017 Vinnie Falco (vinnie dot falco at gmail dot com)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Distributed under the Boost Software License, Version 1.0. (See accompanying
							 | 
						||
| 
								 | 
							
								// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Official repository: https://github.com/boostorg/beast
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								// Example: WebSocket server, synchronous
							 | 
						||
| 
								 | 
							
								//
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <boost/beast/core.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/beast/websocket.hpp>
							 | 
						||
| 
								 | 
							
								#include <boost/asio/ip/tcp.hpp>
							 | 
						||
| 
								 | 
							
								#include <cstdlib>
							 | 
						||
| 
								 | 
							
								#include <functional>
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								#include <string>
							 | 
						||
| 
								 | 
							
								#include <thread>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using tcp = boost::asio::ip::tcp;               // from <boost/asio/ip/tcp.hpp>
							 | 
						||
| 
								 | 
							
								namespace websocket = boost::beast::websocket;  // from <boost/beast/websocket.hpp>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								// Echoes back all received WebSocket messages
							 | 
						||
| 
								 | 
							
								void
							 | 
						||
| 
								 | 
							
								do_session(tcp::socket& socket)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Construct the stream by moving in the socket
							 | 
						||
| 
								 | 
							
								        websocket::stream<tcp::socket> ws{std::move(socket)};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // Accept the websocket handshake
							 | 
						||
| 
								 | 
							
								        ws.accept();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        for(;;)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // This buffer will hold the incoming message
							 | 
						||
| 
								 | 
							
								            boost::beast::multi_buffer buffer;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Read a message
							 | 
						||
| 
								 | 
							
								            ws.read(buffer);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Echo the message back
							 | 
						||
| 
								 | 
							
								            ws.text(ws.got_text());
							 | 
						||
| 
								 | 
							
								            ws.write(buffer.data());
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    catch(boost::system::system_error const& se)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // This indicates that the session was closed
							 | 
						||
| 
								 | 
							
								        if(se.code() != websocket::error::closed)
							 | 
						||
| 
								 | 
							
								            std::cerr << "Error: " << se.code().message() << std::endl;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    catch(std::exception const& e)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        std::cerr << "Error: " << e.what() << std::endl;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								//------------------------------------------------------------------------------
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								int main(int argc, char* argv[])
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								    try
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        // Check command line arguments.
							 | 
						||
| 
								 | 
							
								        if (argc != 3)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            std::cerr <<
							 | 
						||
| 
								 | 
							
								                "Usage: websocket-server-sync <address> <port>\n" <<
							 | 
						||
| 
								 | 
							
								                "Example:\n" <<
							 | 
						||
| 
								 | 
							
								                "    websocket-server-sync 0.0.0.0 8080\n";
							 | 
						||
| 
								 | 
							
								            return EXIT_FAILURE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        auto const address = boost::asio::ip::address::from_string(argv[1]);
							 | 
						||
| 
								 | 
							
								        auto const port = static_cast<unsigned short>(std::atoi(argv[2]));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // The io_service is required for all I/O
							 | 
						||
| 
								 | 
							
								        boost::asio::io_service ios{1};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        // The acceptor receives incoming connections
							 | 
						||
| 
								 | 
							
								        tcp::acceptor acceptor{ios, {address, port}};
							 | 
						||
| 
								 | 
							
								        for(;;)
							 | 
						||
| 
								 | 
							
								        {
							 | 
						||
| 
								 | 
							
								            // This will receive the new connection
							 | 
						||
| 
								 | 
							
								            tcp::socket socket{ios};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Block until we get a connection
							 | 
						||
| 
								 | 
							
								            acceptor.accept(socket);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            // Launch the session, transferring ownership of the socket
							 | 
						||
| 
								 | 
							
								            std::thread{std::bind(
							 | 
						||
| 
								 | 
							
								                &do_session,
							 | 
						||
| 
								 | 
							
								                std::move(socket))}.detach();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    catch (const std::exception& e)
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        std::cerr << "Error: " << e.what() << std::endl;
							 | 
						||
| 
								 | 
							
								        return EXIT_FAILURE;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								}
							 |