Building a program with WebSocket++

As WebSocket++ is a header only library all that is necessary to include it in your program is to include the WebSocket++ repository directory in your include path or alternatively, install the websocketpp code directory somewhere already in your include path.

Required External Libraries

Your program will need to link to external libraries depending on what your build environment looks like. For more information about library dependencies see Required External Libraries.

Creating a program that uses WebSocket++

WebSocket++ provides several types of objects to use to configure and control the WebSocket functionality within your program. The most important of these is the Endpoint. An endpoint represents one of the two roles within a WebSocket connection, client and server.

WebSocket++ endpoints are created by choosing a role and a config. The role determines what sort of operations the endpoint is capable of performing. The config determines what shared components are used and what the default values are. WebSocket++ includes some default configurations you can use out of the box. Advanced users may create their own config types to tailor endpoint behavior to a specific application. More information about exactly how you can set up your own configuration types: [[Configuring Endpoints]].

Default Roles

Role Features Dependencies
server Listen and process WebSocket connections C++11 STL or Boost
client Create outgoing WebSocket connections C++11 STL or Boost

Default Configs

Config Features Dependencies
config::core Low dependency limited feature config with transport based on STL iostreams C++11 STL
config::asio Medium dependency full featured config with Boost ASIO based transport C++11 STL or Boost
libboost_system
pthread
config::asio_tls Higher dependency full featured config with Boost ASIO based transport and TLS support C++11 STL or Boost
libboost_system
pthread
libcrypto
libssl

Each combination of role and config will create an endpoint with different interfaces and behaviors. The types described within the config can add new methods to the Endpoint object. Please refer to the documentation for the config that you are using for more details on the interface it exposes through the endpoint.

Using server<config::asio>

For an initial demonstration we will look at how to use the server role and config::asio config to create a basic WebSocket server that prints out every message it receives. The full example program is listed first, followed by detailed commentary about what each line does.

Program Source

#include <iostream>

#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>

typedef websocketpp::server<websocketpp::config::asio> server;

void on_message(websocketpp::connection_hdl hdl, server::message_ptr msg) {
        std::cout << msg->get_payload() << std::endl;
}

int main() {
    server print_server;

    print_server.set_message_handler(&on_message);

    print_server.init_asio();
    print_server.listen(9002);
    print_server.start_accept();

    print_server.run();
}

Compiling

On Ubuntu 12.04 with websocketpp installed in the user's home directory and Boost installed via the package manager this program can be compiled with:

g++ print_server.cpp -I ~/websocketpp/ -lboost_system

Details

First we include the config and role that we intend to use. In this case we are including asio_no_tls.hpp to avoid pulling in TLS related dependencies for this simple example. config/asio.hpp will include both plain and TLS configs and the dependencies for both. Additionally, we will define a type that specifies which role and config we will be using.

Once in the program itself we will create an endpoint of the type defined above and call some of its member functions.

init_asio() initializes the Asio transport component. This version of init_asio will use an internal io_service managed by the endpoint. See the asio transport component documentation for more information about other ways to initialize asio that use io_services managed directly by your application.

listen(9002) listens on port 9002 of all interface and all address families. The asio transport component provides a number of interfaces for choosing exactly what interface, port, and address family to listen on. This default listen method will listen on the specified port of any interface using both IPv4 and IPv6. See the asio transport component documentation for information on customizing this behavior.

start_accept() tells the server to post the ASIO io_service work actions for accepting new connections. No connections will actually be accepted until the io_service actually runs. If the io_service was running when start_accept is called connections will be accepted immediately.

run()Start the internal asio io_service run loop. This method will block now running the io_service event loop until the server is killed.

Handlers

To instruct the program to perform some action when an event like receiving a message happens we need to register a callback to handle that event. WebSocket++ core implements a number of event handler callbacks and several of its subcomponents are able to define additional handlers of their own. Which handlers are available will depend on what config you are using. A full list of handlers is available.

In the case of our print server, we want the message handler. The message handler takes two arguments, a connection handle and a pointer to the message that was received. The connection handle is a token that uniquely identifies the connection that received the message. It can be used to identify where to send reply messages or stored and used to push messages later. The type of the connection handle is websocketpp::connection_hdl. The message pointer is an object that contains information about a message including the payload, opcode type (text vs binary), and other information. Its type is dependent on the endpoint type and can be retrieved from your endpoint via the message_ptr type. In the case of this simple example, the on_message handler will simply extract the payload from the received message and print it out on the console.

The set_message_handler member function of the endpoint is used to specify which on_message handler to call. This can be changed at any time but will only affect new connections. Individual connections may have their handlers changed after they have been created if needed. set_message_handler takes as a single argument the function to call.

Add new comment

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
By submitting this form, you accept the Mollom privacy policy.