VS2015下使用websocketpp和asio构建websock服务器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jacke121/article/details/88421897

原文:

https://blog.csdn.net/deyafoo/article/details/81508392

如果是boost版,参考链接:

https://blog.csdn.net/byxdaz/article/details/84638249

在https://www.zaphoyd.com/websocketpp下载websocketpp,我用的是0.8.1版。

在http://think-async.com/下载asio库

这个库是说集成到boost中去了,我也不是说Boost不好,但是确实是在某些情况下Boost会有问题。

这个asio库有Makefile文件,但是我编译后也没看到什么lib库出现,估计都是编译sample去了,而库本身是.h Only的。

创建VS2015文件,添加include 路径:{websockpp所在路径}和{asio路径\include}

在Preprocessor中添加预处理器,(告诉websocketpp使用asio库):ASIO_STANDALONE;_WEBSOCKETPP_CPP11_INTERNAL_;ASIO_HAS_STD_TYPE_TRAITS;ASIO_HAS_STD_SHARED_PTR;ASIO_HAS_STD_ADDRESSOF;ASIO_HAS_STD_ATOMIC;ASIO_HAS_STD_CHRONO;ASIO_HAS_CSTDINT;ASIO_HAS_STD_ARRAY;ASIO_HAS_STD_SYSTEM_ERROR;

(这些都是摆脱Boost依赖所用的)

最后的代码如下:

#include <websocketpp/config/asio_no_tls.hpp>
 
#include <websocketpp/server.hpp>
 
#include <iostream>
#include <set>
 
#include <websocketpp/common/thread.hpp>
 
typedef websocketpp::server<websocketpp::config::asio> server;
 
using websocketpp::connection_hdl;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
using websocketpp::lib::bind;
 
using websocketpp::lib::thread;
using websocketpp::lib::mutex;
using websocketpp::lib::lock_guard;
using websocketpp::lib::unique_lock;
using websocketpp::lib::condition_variable;
 
/* on_open insert connection_hdl into channel
* on_close remove connection_hdl from channel
* on_message queue send to all channels
*/
 
enum action_type {
    SUBSCRIBE,
    UNSUBSCRIBE,
    MESSAGE
};
 
struct action {
    action(action_type t, connection_hdl h) : type(t), hdl(h) {}
    action(action_type t, connection_hdl h, server::message_ptr m)
        : type(t), hdl(h), msg(m) {}
 
    action_type type;
    websocketpp::connection_hdl hdl;
    server::message_ptr msg;
};
 
class broadcast_server {
public:
    broadcast_server() {
        // Initialize Asio Transport
        m_server.init_asio();
 
        // Register handler callbacks
        m_server.set_open_handler(bind(&broadcast_server::on_open, this, ::_1));
        m_server.set_close_handler(bind(&broadcast_server::on_close, this, ::_1));
        m_server.set_message_handler(bind(&broadcast_server::on_message, this, ::_1, ::_2));
    }
 
    void run(uint16_t port) {
        // listen on specified port
        m_server.listen(port);
 
        // Start the server accept loop
        m_server.start_accept();
 
        // Start the ASIO io_service run loop
        try {
            m_server.run();
        }
        catch (const std::exception & e) {
            std::cout << e.what() << std::endl;
        }
    }
 
    void on_open(connection_hdl hdl) {
        {
            lock_guard<mutex> guard(m_action_lock);
            //std::cout << "on_open" << std::endl;
            m_actions.push(action(SUBSCRIBE, hdl));
        }
        m_action_cond.notify_one();
    }
 
    void on_close(connection_hdl hdl) {
        {
            lock_guard<mutex> guard(m_action_lock);
            //std::cout << "on_close" << std::endl;
            m_actions.push(action(UNSUBSCRIBE, hdl));
        }
        m_action_cond.notify_one();
    }
 
    void on_message(connection_hdl hdl, server::message_ptr msg) {
        // queue message up for sending by processing thread
        {
            lock_guard<mutex> guard(m_action_lock);
            //std::cout << "on_message" << std::endl;
            m_actions.push(action(MESSAGE, hdl, msg));
        }
        m_action_cond.notify_one();
    }
 
    void process_messages() {
        while (1) {
            unique_lock<mutex> lock(m_action_lock);
 
            while (m_actions.empty()) {
                m_action_cond.wait(lock);
            }
 
            action a = m_actions.front();
            m_actions.pop();
 
            lock.unlock();
 
            if (a.type == SUBSCRIBE) {
                lock_guard<mutex> guard(m_connection_lock);
                m_connections.insert(a.hdl);
            }
            else if (a.type == UNSUBSCRIBE) {
                lock_guard<mutex> guard(m_connection_lock);
                m_connections.erase(a.hdl);
            }
            else if (a.type == MESSAGE) {
                lock_guard<mutex> guard(m_connection_lock);
 
                con_list::iterator it;
                for (it = m_connections.begin(); it != m_connections.end(); ++it) {
                    m_server.send(*it, a.msg);
                }
            }
            else {
                // undefined.
            }
        }
    }
private:
    typedef std::set<connection_hdl, std::owner_less<connection_hdl> > con_list;
 
    server m_server;
    con_list m_connections;
    std::queue<action> m_actions;
 
    mutex m_action_lock;
    mutex m_connection_lock;
    condition_variable m_action_cond;
};
 
int main() {
    try {
        broadcast_server server_instance;
 
        // Start a thread to run the processing loop
        thread t(bind(&broadcast_server::process_messages, &server_instance));
 
        // Run the asio loop with the main thread
        server_instance.run(9002);
 
        t.join();
 
    }
    catch (websocketpp::exception const & e) {
        std::cout << e.what() << std::endl;
    }

}


<!DOCTYPE html>    
<html>    
 
<head>    
 
<meta charset="UTF-8">  
 
</head>    
 
<body>    
 
    <div>    
 
        <input type="submit" value="Start" onclick="startSendDataToServer()" />    
 
    </div>    
 
    <div id="messages"></div>    
 
    <script type="text/javascript">    
 
        //var webSocket =  new WebSocket('ws://localhost:9100/websocket?userid=admin');  
 
        var webSocket =  new WebSocket('ws://localhost:9100');  
 
    
 
        webSocket.onerror = function(event) {    
 
            onError(event)    
 
        };    
 
    
 
        webSocket.onopen = function(event) {    
 
            onOpen(event)    
 
        };    
 
    
 
        webSocket.onmessage = function(event) {    
 
            onMessage(event)    
 
        };    
 
    
 
        function onMessage(event) {    
 
            document.getElementById('messages').innerHTML     
 
                += '<br />Get Message From Server: ' + event.data;    
 
        }    
 
    
 
        function onOpen(event) {    
 
            document.getElementById('messages').innerHTML     
 
                = 'Connection established';    
 
        }    
 
    
 
        function onError(event) {    
 
            alert(event.data);    
 
            alert("error");    
 
        }    
 
    
 
        function startSendDataToServer() {
            webSocket.send('hello');    
            return false;    
 
        }    
 
    </script>    
 
</body>    
 
</html>

猜你喜欢

转载自blog.csdn.net/jacke121/article/details/88421897
今日推荐