私は、オーディオ サーバーのストリーミング機能をテストすることを目的とした C++ の負荷テスト アプリに取り組んでいます。このクライアントでは、websocketpp を使用しており、この例に従いました。
私はいつも行にsigsegvを取得します
con = endpoint.get_connection(connection_string);
私の Workthread::Work メソッドの。
メインアプリは疑似コードで次のようになります
namespace blah
{
TestmanagerClass::run()
{
start (additional) threads until limit n is reached;
call workthread::work() method of each thread;
handle finished threads;
goto 1;
}
}
これは WorkThread::work() です。認証コードを疑似コードに置き換えました...
namespace blah {
void WorkThread::work()
{
AudioStreamHandlerPtr handler(new AudioStreamHandler());
websocketpp::client::connection_ptr con;
websocketpp::client endpoint(handler);
try
{
// authenticate
// get login/access token from webservice
if( !worksOutFine )
{
logError();
}
else
{ // got access token :D
// now obtain session token from session service
if( !worksOutFine )
{
logError();
}
else
{ // process this session's calls
std::string connection_string = "ws://localhost";//boost::str(boost::format("ws://%1%/data?user_id=%2%&session_token=%3%") % serverAddressNoPort % session_.userId % sessionToken);
std::cout << "CONNECTIONSTRING " << connection_string << std::endl;
con = endpoint.get_connection(connection_string);
std::cout << "1" << std::endl;
endpoint.connect(con);
std::cout << "2" << std::endl;
boost::thread t(boost::bind(& websocketpp::client::run, &endpoint, false));
more code....
}
}
接続文字列の出力は最後に機能します。「1」は出ませんが、sigsegv が発生します。
これは、エンドポイントのコンストラクターに渡されるハンドラーのコードです。
ヘッダ:
#ifndef __AUDIOSTREAMHANDLER_H__
#define __AUDIOSTREAMHANDLER_H__
#include <boost/shared_ptr.hpp>
#include <websocketpp/roles/client.hpp>
#include <websocketpp/websocketpp.hpp>
namespace blah
{
class AudioStreamHandler : public websocketpp::client::handler
{
private:
connection_ptr con_;
public:
AudioStreamHandler();
virtual ~AudioStreamHandler();
void on_fail(connection_ptr con);
void on_open(connection_ptr con);
void on_close(connection_ptr con);
void on_message(connection_ptr con, message_ptr msg);
void send(const std::string &msg);
void close();
};
typedef boost::shared_ptr<AudioStreamHandler> AudioStreamHandlerPtr;
}
#endif //__AUDIOSTREAMHANDLER_H__
実装:
#include "AudioStreamHandler.h"
namespace blah
{
AudioStreamHandler::AudioStreamHandler()
{
}
AudioStreamHandler::~AudioStreamHandler()
{
}
void AudioStreamHandler::on_fail(connection_ptr con)
{
std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSocket connection failed <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
}
void AudioStreamHandler::on_open(connection_ptr con)
{
con_ = con;
std::cout << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebSocket connection established <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
}
void AudioStreamHandler::on_close(connection_ptr con)
{
con_ = websocketpp::client::connection_ptr();
std::cout << "WebSocket connection terminated" << std::endl;
}
void AudioStreamHandler::on_message(connection_ptr con, message_ptr msg)
{
std::cout << "Got WebSocket message: " << msg->get_payload() << std::endl;
}
void AudioStreamHandler::send(const std::string &msg)
{
if( con_ ) {
std::cerr << "Error: no connected session" << std::endl;
return;
}
if( msg == "/close" ) {
close();
} else {
con_->send(msg);
}
}
void AudioStreamHandler::close() {
if( !con_ ) {
std::cerr << "Error: no connected session" << std::endl;
return;
}
con_->close(websocketpp::close::status::GOING_AWAY,"");
}
}
最後に、gdb から取得したスタックトレース:
(gdb) where
#0 0x00000000004aeabd in boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_all_states() ()
#1 0x00000000004af293 in boost::re_detail::perl_matcher<char const*, std::allocator<boost::sub_match<char const*> >, boost::regex_traits<char, boost::cpp_regex_traits<char> > >::match_imp() ()
#2 0x00000000004afeb4 in bool boost::regex_match<char const*, std::allocator<boost::sub_match<char const*> >, char, boost::regex_traits<char, boost::cpp_regex_traits<char> > >(char const*, char const*, boost::match_results<char const*, std::allocator<boost::sub_match<char const*> > >&, boost::basic_regex<char, boost::regex_traits<char, boost::cpp_regex_traits<char> > > const&, boost::regex_constants::_match_flags) ()
#3 0x00000000004a9c47 in websocketpp::uri::uri(std::string const&) ()
#4 0x0000000000441254 in websocketpp::role::client<websocketpp::endpoint<websocketpp::role::client, websocketpp::socket::plain, websocketpp::log::logger> >::get_connection(std::string const&) (this=0x7ffff2501450)
at /usr/include/c++/4.4/bits/stl_vector.h:313
#5 0x0000000000426130 in blah::WorkThread::work (this=0x7c4250) at workthread.cpp:93
#6 0x000000000049658d in boost::_mfi::mf0<void, blah::WorkThread>::operator()(blah::WorkThread*) const (this=0x789cc8) at /usr/include/c++/4.4/ext/new_allocator.h:66
#7 0x0000000000495ffc in void boost::_bi::list1<boost::_bi::value<blah::WorkThread*> >::operator()<boost::_mfi::mf0<void, blah::WorkThread>, boost::_bi::list0>(boost::_bi::type<void>, boost::_mfi::mf0<void, blah::WorkThread>&, boost::_bi::list0&, int) (this=0x789cd8) at /usr/include/c++/4.4/ext/new_allocator.h:66
#8 0x00000000004957eb in boost::_bi::bind_t<void, boost::_mfi::mf0<void, blah::WorkThread>, boost::_bi::list1<boost::_bi::value<blah::WorkThread*> > >::operator()() (this=0x800000) at /usr/include/c++/4.4/ext/new_allocator.h:66
#9 0x0000000000493a26 in boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, blah::WorkThread>, boost::_bi::list1<boost::_bi::value<blah::WorkThread*> > > >::run() (this=0x789b40)
at /usr/include/c++/4.4/ext/new_allocator.h:66
#10 0x00007ffff79b1693 in thread_proxy () from /usr/lib/libboost_thread.so.1.49.0
#11 0x00007ffff5ade9ca in start_thread (arg=<value optimized out>) at pthread_create.c:300
#12 0x00007ffff5ddbcdd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#13 0x0000000000000000 in ?? ()
すでにブーストのデバッグ ビルドを試しましたが、それ以上のエラー情報は得られませんでした。また、単純に「ws://localhost」を使用するか、実際の接続文字列 / uri を使用するかは問題ではありません。
誰かが同じ問題を経験したか、ここで私が間違っていることを誰かに知っていますか? どんな助けでも大歓迎です。この長い投稿をお読みいただきありがとうございます。