mirror of
https://github.com/twisterarmy/twister-core.git
synced 2025-08-26 13:51:49 +00:00
WebSocket...
This commit is contained in:
parent
0c72baa9b1
commit
0e63a70c7c
@ -189,6 +189,7 @@ twisterd_LDADD = $(LIBLEVELDB) $(LIBMEMENV) \
|
|||||||
|
|
||||||
AM_CPPFLAGS = -ftemplate-depth-100 -DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 \
|
AM_CPPFLAGS = -ftemplate-depth-100 -DBOOST_SPIRIT_THREADSAFE -D_FILE_OFFSET_BITS=64 \
|
||||||
-I$(top_srcdir)/libtorrent/include \
|
-I$(top_srcdir)/libtorrent/include \
|
||||||
|
-I$(top_srcdir)/websocketpp \
|
||||||
-I$(top_srcdir)/src \
|
-I$(top_srcdir)/src \
|
||||||
-I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \
|
-I$(top_srcdir)/src/leveldb/include -I$(top_srcdir)/src/leveldb/helpers \
|
||||||
@DEBUGFLAGS@ @BOOST_CPPFLAGS@ @OPENSSL_INCLUDES@ @DB_CXX_CPPFLAGS@
|
@DEBUGFLAGS@ @BOOST_CPPFLAGS@ @OPENSSL_INCLUDES@ @DB_CXX_CPPFLAGS@
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
|
git submodule update --init
|
||||||
|
|
||||||
./autotool.sh
|
./autotool.sh
|
||||||
./configure $@
|
./configure $@
|
||||||
|
|
||||||
|
@ -35,6 +35,29 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <streambuf>
|
#include <streambuf>
|
||||||
|
|
||||||
|
#include <websocketpp/config/asio_no_tls_client.hpp>
|
||||||
|
#include <websocketpp/client.hpp>
|
||||||
|
#include <websocketpp/config/asio_no_tls.hpp>
|
||||||
|
#include <websocketpp/server.hpp>
|
||||||
|
#include <websocketpp/config/asio.hpp>
|
||||||
|
#include <websocketpp/config/asio_client.hpp>
|
||||||
|
|
||||||
|
typedef websocketpp::server<websocketpp::config::asio> wsserver;
|
||||||
|
typedef websocketpp::client<websocketpp::config::asio_client> wsclient;
|
||||||
|
|
||||||
|
typedef websocketpp::server<websocketpp::config::asio_tls> swsserver;
|
||||||
|
typedef websocketpp::client<websocketpp::config::asio_tls_client> swsclient;
|
||||||
|
|
||||||
|
using websocketpp::lib::placeholders::_1;
|
||||||
|
using websocketpp::lib::placeholders::_2;
|
||||||
|
|
||||||
|
typedef websocketpp::config::asio_client::message_type::ptr message_ptr;
|
||||||
|
typedef websocketpp::lib::shared_ptr<websocketpp::lib::asio::ssl::context> context_ptr;
|
||||||
|
|
||||||
|
wsserver wss;
|
||||||
|
swsserver swss;
|
||||||
|
vector<websocketpp::connection_hdl> wsconnections;
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace boost;
|
using namespace boost;
|
||||||
using namespace boost::asio;
|
using namespace boost::asio;
|
||||||
@ -290,6 +313,7 @@ static const CRPCCommand vRPCCommands[] =
|
|||||||
{ "uidtousername", &uidtousername, false, true, true },
|
{ "uidtousername", &uidtousername, false, true, true },
|
||||||
{ "newshorturl", &newshorturl, false, true, false },
|
{ "newshorturl", &newshorturl, false, true, false },
|
||||||
{ "decodeshorturl", &decodeshorturl, false, true, true },
|
{ "decodeshorturl", &decodeshorturl, false, true, true },
|
||||||
|
// { "openwebsocket", &openwebsocket, false, true, true },
|
||||||
};
|
};
|
||||||
|
|
||||||
CRPCTable::CRPCTable()
|
CRPCTable::CRPCTable()
|
||||||
@ -759,8 +783,127 @@ static void RPCAcceptHandler(boost::shared_ptr< basic_socket_acceptor<Protocol>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class WST>
|
||||||
|
void on_message_server(WST *s, websocketpp::connection_hdl hdl, message_ptr msg);
|
||||||
|
template <class WST>
|
||||||
|
void on_connection(WST *s, websocketpp::connection_hdl hdl)
|
||||||
|
{
|
||||||
|
wsconnections.push_back(hdl);
|
||||||
|
|
||||||
|
s->send(hdl, "{\"result\":\"twister WEB Socket...\"}", websocketpp::frame::opcode::text);
|
||||||
|
}
|
||||||
|
template <class WST>
|
||||||
|
void on_close(WST *s, websocketpp::connection_hdl hdl)
|
||||||
|
{
|
||||||
|
typename WST::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||||
|
vector<websocketpp::connection_hdl>::iterator it;
|
||||||
|
for (it = wsconnections.begin(); it != wsconnections.end(); ++it)
|
||||||
|
{
|
||||||
|
if (s->get_con_from_hdl(*it) == con)
|
||||||
|
{
|
||||||
|
wsconnections.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
context_ptr on_tls_init(websocketpp::connection_hdl hdl)
|
||||||
|
{
|
||||||
|
namespace asio = websocketpp::lib::asio;
|
||||||
|
|
||||||
|
context_ptr ctx = websocketpp::lib::make_shared<asio::ssl::context>(asio::ssl::context::sslv23);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ctx->set_options(asio::ssl::context::default_workarounds |
|
||||||
|
asio::ssl::context::no_sslv2 |
|
||||||
|
asio::ssl::context::no_sslv3 |
|
||||||
|
asio::ssl::context::single_dh_use);
|
||||||
|
|
||||||
|
ctx->use_certificate_chain_file(GetArg("-rpcsslcertificatechainfile", "server.cert"));
|
||||||
|
ctx->use_private_key_file(GetArg("-rpcsslprivatekeyfile", "server.pem"), asio::ssl::context::pem);
|
||||||
|
|
||||||
|
std::string ciphers = GetArg("-rpcsslciphers", "TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH");
|
||||||
|
|
||||||
|
if (SSL_CTX_set_cipher_list(ctx->native_handle() , ciphers.c_str()) != 1)
|
||||||
|
std::cout << "Error setting cipher list" << std::endl;
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
std::cout << "Exception: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ws_tls_handler(swsserver &ws)
|
||||||
|
{
|
||||||
|
ws.set_tls_init_handler(websocketpp::lib::bind(&on_tls_init, ::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ws_tls_handler(wsserver &ws){}
|
||||||
|
|
||||||
|
void set_ws_tls_handler(swsclient &ws)
|
||||||
|
{
|
||||||
|
ws.set_tls_init_handler(websocketpp::lib::bind(&on_tls_init, ::_1));
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_ws_tls_handler(wsclient &ws){}
|
||||||
|
|
||||||
|
template <class WST>
|
||||||
|
void StartWSServer(WST &ws)
|
||||||
|
{
|
||||||
|
//wsserver ws;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Set logging settings
|
||||||
|
//ws.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
//ws.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
ws.set_access_channels(websocketpp::log::alevel::none);
|
||||||
|
ws.clear_access_channels(websocketpp::log::alevel::all);
|
||||||
|
|
||||||
|
|
||||||
|
// Initialize Asio
|
||||||
|
ws.init_asio();
|
||||||
|
|
||||||
|
// Register our message handler
|
||||||
|
ws.set_message_handler(websocketpp::lib::bind(&on_message_server<WST>, &ws, ::_1, ::_2));
|
||||||
|
ws.set_open_handler(websocketpp::lib::bind(&on_connection<WST>, &ws, ::_1));
|
||||||
|
ws.set_close_handler(websocketpp::lib::bind(&on_close<WST>, &ws, ::_1));
|
||||||
|
|
||||||
|
set_ws_tls_handler(ws);
|
||||||
|
|
||||||
|
// Listen
|
||||||
|
ws.listen(GetArg("-wsport", GetArg("-rpcport", Params().RPCPort()) + 1000));
|
||||||
|
|
||||||
|
// Start the server accept loop
|
||||||
|
ws.start_accept();
|
||||||
|
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
ws.run();
|
||||||
|
}
|
||||||
|
catch (websocketpp::exception const & e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << std::endl;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
std::cout << "other exception" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void StartRPCThreads()
|
void StartRPCThreads()
|
||||||
{
|
{
|
||||||
|
const bool fUseSSL = GetBoolArg("-rpcssl", false);
|
||||||
|
if (GetBoolArg("-websocket", false))
|
||||||
|
{
|
||||||
|
if (fUseSSL)
|
||||||
|
boost::thread wst(boost::bind(&StartWSServer<swsserver>, boost::ref<swsserver>(swss)));
|
||||||
|
else
|
||||||
|
boost::thread wst(boost::bind(&StartWSServer<wsserver>, boost::ref<wsserver>(wss)));
|
||||||
|
}
|
||||||
|
if (!GetBoolArg("-jsonrpc", true))
|
||||||
|
return;
|
||||||
|
|
||||||
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
|
strRPCUserColonPass = mapArgs["-rpcuser"] + ":" + mapArgs["-rpcpassword"];
|
||||||
if (((mapArgs["-rpcpassword"] == "") ||
|
if (((mapArgs["-rpcpassword"] == "") ||
|
||||||
(mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
|
(mapArgs["-rpcuser"] == mapArgs["-rpcpassword"])) && Params().RequireRPCPassword())
|
||||||
@ -796,8 +939,6 @@ void StartRPCThreads()
|
|||||||
rpc_io_service = new asio::io_service();
|
rpc_io_service = new asio::io_service();
|
||||||
rpc_ssl_context = new ssl::context(ssl::context::sslv23);
|
rpc_ssl_context = new ssl::context(ssl::context::sslv23);
|
||||||
|
|
||||||
const bool fUseSSL = GetBoolArg("-rpcssl", false);
|
|
||||||
|
|
||||||
if (fUseSSL)
|
if (fUseSSL)
|
||||||
{
|
{
|
||||||
rpc_ssl_context->set_options(ssl::context::no_sslv2);
|
rpc_ssl_context->set_options(ssl::context::no_sslv2);
|
||||||
@ -907,7 +1048,7 @@ void RPCRunLater(const std::string& name, boost::function<void(void)> func, int6
|
|||||||
boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
|
boost::shared_ptr<deadline_timer>(new deadline_timer(*rpc_io_service))));
|
||||||
}
|
}
|
||||||
deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
|
deadlineTimers[name]->expires_from_now(posix_time::seconds(nSeconds));
|
||||||
deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, _1, func));
|
deadlineTimers[name]->async_wait(boost::bind(RPCRunHandler, boost::placeholders::_1, func));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1175,9 +1316,152 @@ json_spirit::Value CRPCTable::execute(const std::string &strMethod, const json_s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class WST>
|
||||||
|
void on_message_client(WST* c, websocketpp::connection_hdl hdl, message_ptr msg)
|
||||||
|
{
|
||||||
|
string strPrint;
|
||||||
|
int nRet = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse reply
|
||||||
|
Value valReply;
|
||||||
|
if (!read_string(msg->get_payload(), valReply))
|
||||||
|
throw runtime_error("couldn't parse reply from server");
|
||||||
|
const Object& reply = valReply.get_obj();
|
||||||
|
if (reply.empty())
|
||||||
|
throw runtime_error("expected reply to have result, error and id properties");
|
||||||
|
|
||||||
|
// Parse reply
|
||||||
|
const Value& result = find_value(reply, "result");
|
||||||
|
const Value& error = find_value(reply, "error");
|
||||||
|
|
||||||
|
if (error.type() != null_type)
|
||||||
|
{
|
||||||
|
// Error
|
||||||
|
strPrint = "error: " + write_string(error, false);
|
||||||
|
int code = find_value(error.get_obj(), "code").get_int();
|
||||||
|
nRet = abs(code);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Result
|
||||||
|
if (result.type() == null_type)
|
||||||
|
strPrint = "";
|
||||||
|
else if (result.type() == str_type)
|
||||||
|
strPrint = result.get_str();
|
||||||
|
else
|
||||||
|
strPrint = write_string(result, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (boost::thread_interrupted)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
catch (std::exception& e) {
|
||||||
|
strPrint = string("error: ") + e.what();
|
||||||
|
nRet = 87;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
PrintException(NULL, "CommandLineRPC()");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strPrint != "")
|
||||||
|
{
|
||||||
|
fprintf((nRet == 0 ? stdout : stderr), "%s\n", strPrint.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class WST>
|
||||||
|
Object StartWSClient(bool fUseSSL)
|
||||||
|
{
|
||||||
|
WST c;
|
||||||
|
|
||||||
|
stringstream ssuri;
|
||||||
|
ssuri << "ws" << (fUseSSL ? "s" : "") <<"://" << GetArg("-rpcconnect", "127.0.0.1") << ":" << GetArg("-wsport", GetArg("-rpcport", Params().RPCPort()) + 1000);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Set logging to be pretty verbose (everything except message payloads)
|
||||||
|
//c.set_access_channels(websocketpp::log::alevel::all);
|
||||||
|
//c.clear_access_channels(websocketpp::log::alevel::frame_payload);
|
||||||
|
c.set_access_channels(websocketpp::log::alevel::none);
|
||||||
|
c.clear_access_channels(websocketpp::log::alevel::all);
|
||||||
|
|
||||||
|
// Initialize ASIO
|
||||||
|
c.init_asio();
|
||||||
|
//c.start_perpetual();
|
||||||
|
boost::thread wsth(boost::bind(&WST::run, &c));
|
||||||
|
|
||||||
|
// Register our message handler
|
||||||
|
c.set_message_handler(websocketpp::lib::bind(&on_message_client<WST>, &c, ::_1, ::_2));
|
||||||
|
set_ws_tls_handler(c);
|
||||||
|
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
typename WST::connection_ptr con = c.get_connection(ssuri.str(), ec);
|
||||||
|
if (ec) {
|
||||||
|
std::cout << "could not create connection because: " << ec.message() << std::endl;
|
||||||
|
Object reply;
|
||||||
|
reply.push_back(Pair("error", ec.message()));
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that connect here only requests a connection. No network messages are
|
||||||
|
// exchanged until the event loop starts running in the next line.
|
||||||
|
c.connect(con);
|
||||||
|
|
||||||
|
// Start the ASIO io_service run loop
|
||||||
|
// this will cause a single connection to be made to the server. c.run()
|
||||||
|
// will exit when this connection is closed.
|
||||||
|
//c.run();
|
||||||
|
|
||||||
|
string strCommand;
|
||||||
|
while (strCommand != "closewebsocket" && strCommand != "stop")
|
||||||
|
{
|
||||||
|
getline(cin, strCommand);
|
||||||
|
|
||||||
|
vector<string> tokens;
|
||||||
|
boost::algorithm::split(tokens, strCommand, boost::algorithm::is_any_of(" "));
|
||||||
|
|
||||||
|
// Method
|
||||||
|
if (tokens.size() < 1)
|
||||||
|
continue;
|
||||||
|
vector<string>::iterator it = tokens.begin();
|
||||||
|
string method = *it;
|
||||||
|
|
||||||
|
// Parameters default to strings
|
||||||
|
vector<string> strParams(++it, tokens.end());
|
||||||
|
Array params = RPCConvertValues(method, strParams);
|
||||||
|
|
||||||
|
string strRequest = JSONRPCRequest(method, params, 1);
|
||||||
|
c.send(con->get_handle(), strRequest, websocketpp::frame::opcode::text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (websocketpp::exception const & e)
|
||||||
|
{
|
||||||
|
std::cout << e.what() << std::endl;
|
||||||
|
|
||||||
|
Object reply;
|
||||||
|
reply.push_back(Pair("error", e.what()));
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
Object reply;
|
||||||
|
reply.push_back(Pair("result", "OK"));
|
||||||
|
return reply;
|
||||||
|
}
|
||||||
|
|
||||||
Object CallRPC(const string& strMethod, const Array& params)
|
Object CallRPC(const string& strMethod, const Array& params)
|
||||||
{
|
{
|
||||||
|
bool fUseSSL = GetBoolArg("-rpcssl", false);
|
||||||
|
if (strMethod == "openwebsocket")
|
||||||
|
{
|
||||||
|
if (fUseSSL)
|
||||||
|
return StartWSClient<swsclient>(fUseSSL);
|
||||||
|
else
|
||||||
|
return StartWSClient<wsclient>(fUseSSL);
|
||||||
|
}
|
||||||
|
|
||||||
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
|
if (mapArgs["-rpcuser"] == "" && mapArgs["-rpcpassword"] == "")
|
||||||
throw runtime_error(strprintf(
|
throw runtime_error(strprintf(
|
||||||
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
|
_("You must set rpcpassword=<password> in the configuration file:\n%s\n"
|
||||||
@ -1185,7 +1469,6 @@ Object CallRPC(const string& strMethod, const Array& params)
|
|||||||
GetConfigFile().string().c_str()));
|
GetConfigFile().string().c_str()));
|
||||||
|
|
||||||
// Connect to localhost
|
// Connect to localhost
|
||||||
bool fUseSSL = GetBoolArg("-rpcssl", false);
|
|
||||||
asio::io_service io_service;
|
asio::io_service io_service;
|
||||||
ssl::context context(ssl::context::sslv23);
|
ssl::context context(ssl::context::sslv23);
|
||||||
context.set_options(ssl::context::no_sslv2);
|
context.set_options(ssl::context::no_sslv2);
|
||||||
@ -1445,7 +1728,95 @@ int CommandLineRPC(int argc, char *argv[])
|
|||||||
return nRet;
|
return nRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class WST>
|
||||||
|
void on_message_server(WST* s, websocketpp::connection_hdl hdl, message_ptr msg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
std::cout << "on_message called with hdl: " << hdl.lock().get()
|
||||||
|
<< " and message: " << msg->get_payload()
|
||||||
|
<< std::endl;
|
||||||
|
*/
|
||||||
|
|
||||||
|
// check for a special command to instruct the server to stop listening so
|
||||||
|
// it can be cleanly exited.
|
||||||
|
if (msg->get_payload() == "closewebsocket")
|
||||||
|
{
|
||||||
|
s->stop_listening();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONRequest jreq;
|
||||||
|
string strReply;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// Parse request
|
||||||
|
Value valRequest;
|
||||||
|
if (!read_string(msg->get_payload(), valRequest))
|
||||||
|
throw JSONRPCError(RPC_PARSE_ERROR, "Parse error");
|
||||||
|
|
||||||
|
// singleton request
|
||||||
|
if (valRequest.type() == obj_type)
|
||||||
|
{
|
||||||
|
jreq.parse(valRequest);
|
||||||
|
|
||||||
|
Value result = tableRPC.execute(jreq.strMethod, jreq.params);
|
||||||
|
|
||||||
|
// Send reply
|
||||||
|
strReply = JSONRPCReply(result, Value::null, jreq.id);
|
||||||
|
|
||||||
|
if (jreq.strMethod == "stop")
|
||||||
|
s->stop_listening();
|
||||||
|
}
|
||||||
|
else if (valRequest.type() == array_type)
|
||||||
|
strReply = JSONRPCExecBatch(valRequest.get_array());
|
||||||
|
else
|
||||||
|
throw JSONRPCError(RPC_PARSE_ERROR, "Top-level object parse error");
|
||||||
|
}
|
||||||
|
catch (Object& objError)
|
||||||
|
{
|
||||||
|
strReply = JSONRPCReply(Value::null, objError, jreq.id);
|
||||||
|
}
|
||||||
|
catch (std::exception& e)
|
||||||
|
{
|
||||||
|
strReply = e.what();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
s->send(hdl, strReply, msg->get_opcode());
|
||||||
|
}
|
||||||
|
catch (const websocketpp::lib::error_code& e)
|
||||||
|
{
|
||||||
|
std::cout << "Echo failed because: " << e
|
||||||
|
<< "(" << e.message() << ")" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteToWS(Value const& val)
|
||||||
|
{
|
||||||
|
string strPrint;
|
||||||
|
bool fUseSSL = GetBoolArg("-rpcssl", false);
|
||||||
|
|
||||||
|
if (val.type() == null_type)
|
||||||
|
return;
|
||||||
|
else if (val.type() == str_type)
|
||||||
|
strPrint = val.get_str();
|
||||||
|
else
|
||||||
|
strPrint = write_string(val, false);
|
||||||
|
|
||||||
|
for (vector<websocketpp::connection_hdl>::iterator it = wsconnections.begin(); it != wsconnections.end(); ++it)
|
||||||
|
{
|
||||||
|
websocketpp::lib::error_code ec;
|
||||||
|
if (fUseSSL)
|
||||||
|
swss.send(*it, strPrint, websocketpp::frame::opcode::text, ec);
|
||||||
|
else
|
||||||
|
wss.send(*it, strPrint, websocketpp::frame::opcode::text, ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
cout << "ERROR : " << ec.message() << endl << ec << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
@ -74,6 +74,8 @@ void StartRPCThreads();
|
|||||||
void StopRPCThreads();
|
void StopRPCThreads();
|
||||||
int CommandLineRPC(int argc, char *argv[]);
|
int CommandLineRPC(int argc, char *argv[]);
|
||||||
|
|
||||||
|
void WriteToWS(json_spirit::Value const& val);
|
||||||
|
|
||||||
/** Convert parameter values for RPC call from strings to command-specific JSON objects. */
|
/** Convert parameter values for RPC call from strings to command-specific JSON objects. */
|
||||||
json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams);
|
json_spirit::Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams);
|
||||||
|
|
||||||
|
@ -231,6 +231,7 @@ std::string HelpMessage()
|
|||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
strUsage += " -printtodebugger " + _("Send trace/debug info to debugger") + "\n";
|
strUsage += " -printtodebugger " + _("Send trace/debug info to debugger") + "\n";
|
||||||
#endif
|
#endif
|
||||||
|
strUsage += " -jsonrpc " + _("Enable JSON-RPC service (default: 1)") + "\n";
|
||||||
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
strUsage += " -rpcuser=<user> " + _("Username for JSON-RPC connections") + "\n";
|
||||||
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
strUsage += " -rpcpassword=<pw> " + _("Password for JSON-RPC connections") + "\n";
|
||||||
strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 28332 or testnet: 18332)") + "\n";
|
strUsage += " -rpcport=<port> " + _("Listen for JSON-RPC connections on <port> (default: 28332 or testnet: 18332)") + "\n";
|
||||||
@ -238,6 +239,9 @@ std::string HelpMessage()
|
|||||||
if (!fHaveGUI)
|
if (!fHaveGUI)
|
||||||
strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
|
strUsage += " -rpcconnect=<ip> " + _("Send commands to node running on <ip> (default: 127.0.0.1)") + "\n";
|
||||||
strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 10)") + "\n";
|
strUsage += " -rpcthreads=<n> " + _("Set the number of threads to service RPC calls (default: 10)") + "\n";
|
||||||
|
strUsage += " -websocket " + _("Enables WEB Socket connections (default: 0)") + "\n";
|
||||||
|
strUsage += " -wsport=<port> " + _("Listen for WEB Socket on <port> (default: rpcport+1000)") + "\n";
|
||||||
|
|
||||||
strUsage += " -public_server_mode " + _("Limit JSON-RPC execution to public/safe commands only.") + "\n";
|
strUsage += " -public_server_mode " + _("Limit JSON-RPC execution to public/safe commands only.") + "\n";
|
||||||
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
|
strUsage += " -blocknotify=<cmd> " + _("Execute command when the best block changes (%s in cmd is replaced by block hash)") + "\n";
|
||||||
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
|
strUsage += " -walletnotify=<cmd> " + _("Execute command when a wallet transaction changes (%s in cmd is replaced by TxID)") + "\n";
|
||||||
@ -259,7 +263,7 @@ std::string HelpMessage()
|
|||||||
strUsage += " -blockprioritysize=<n> " + _("Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)") + "\n";
|
strUsage += " -blockprioritysize=<n> " + _("Set maximum size of high-priority/low-fee transactions in bytes (default: 27000)") + "\n";
|
||||||
|
|
||||||
strUsage += "\n"; _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
strUsage += "\n"; _("SSL options: (see the Bitcoin Wiki for SSL setup instructions)") + "\n";
|
||||||
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC connections") + "\n";
|
strUsage += " -rpcssl " + _("Use OpenSSL (https) for JSON-RPC and/or WEB Socket connections") + "\n";
|
||||||
strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n";
|
strUsage += " -rpcsslcertificatechainfile=<file.cert> " + _("Server certificate file (default: server.cert)") + "\n";
|
||||||
strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n";
|
strUsage += " -rpcsslprivatekeyfile=<file.pem> " + _("Server private key (default: server.pem)") + "\n";
|
||||||
strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
|
strUsage += " -rpcsslciphers=<ciphers> " + _("Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)") + "\n";
|
||||||
|
@ -1440,6 +1440,23 @@ bool processReceivedDM(lazy_entry const* post)
|
|||||||
} else {
|
} else {
|
||||||
storeNewDM(item.second.username, fromMe ? to : from, stoDM);
|
storeNewDM(item.second.username, fromMe ? to : from, stoDM);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetBoolArg("-websocket", false) && !fromMe)
|
||||||
|
{
|
||||||
|
Object dm;
|
||||||
|
|
||||||
|
dm.push_back(Pair("type", isGroup ? "GROUP" : "DM"));
|
||||||
|
if (isGroup)
|
||||||
|
dm.push_back(Pair("group", item.second.username));
|
||||||
|
dm.push_back(Pair("k", k));
|
||||||
|
dm.push_back(Pair("time", utcTime));
|
||||||
|
dm.push_back(Pair("from", from));
|
||||||
|
dm.push_back(Pair("to", to));
|
||||||
|
dm.push_back(Pair("msg", msg));
|
||||||
|
|
||||||
|
WriteToWS(dm);
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1474,17 +1491,55 @@ void processReceivedPost(lazy_entry const &v, std::string &username, int64 time,
|
|||||||
|
|
||||||
LOCK(cs_twister);
|
LOCK(cs_twister);
|
||||||
// mention of a local user && sent by someone we follow
|
// mention of a local user && sent by someone we follow
|
||||||
if( m_users.count(mentionUser) && m_users[mentionUser].m_following.count(username) ) {
|
if( m_users.count(mentionUser) && m_users[mentionUser].m_following.count(username) )
|
||||||
|
{
|
||||||
std::string postKey = username + ";" + boost::lexical_cast<std::string>(time);
|
std::string postKey = username + ";" + boost::lexical_cast<std::string>(time);
|
||||||
if( m_users[mentionUser].m_mentionsKeys.count(postKey) == 0 ) {
|
if( m_users[mentionUser].m_mentionsKeys.count(postKey) == 0 )
|
||||||
|
{
|
||||||
m_users[mentionUser].m_mentionsKeys.insert(postKey);
|
m_users[mentionUser].m_mentionsKeys.insert(postKey);
|
||||||
entry vEntry;
|
entry vEntry;
|
||||||
vEntry = v;
|
vEntry = v;
|
||||||
m_users[mentionUser].m_mentionsPosts.push_back(vEntry);
|
m_users[mentionUser].m_mentionsPosts.push_back(vEntry);
|
||||||
|
|
||||||
|
if (GetBoolArg("-websocket", false))
|
||||||
|
{
|
||||||
|
Object obj;
|
||||||
|
|
||||||
|
obj.push_back(Pair("type", "mention"));
|
||||||
|
obj.push_back(Pair("from", username));
|
||||||
|
obj.push_back(Pair("to", mentionUser));
|
||||||
|
hexcapePost(vEntry);
|
||||||
|
obj.push_back(Pair("post", entryToJson(vEntry)));
|
||||||
|
|
||||||
|
WriteToWS(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (GetBoolArg("-websocket", false))
|
||||||
|
{
|
||||||
|
entry vEntry;
|
||||||
|
vEntry = v;
|
||||||
|
for (map<string, UserData>::const_iterator it = m_users.begin();
|
||||||
|
it != m_users.end();
|
||||||
|
++it)
|
||||||
|
{
|
||||||
|
if (it->second.m_following.count(username))
|
||||||
|
{
|
||||||
|
Object obj;
|
||||||
|
|
||||||
|
obj.push_back(Pair("type", "post"));
|
||||||
|
obj.push_back(Pair("postboard", it->first));
|
||||||
|
obj.push_back(Pair("from", username));
|
||||||
|
hexcapePost(vEntry);
|
||||||
|
obj.push_back(Pair("post", entryToJson(vEntry)));
|
||||||
|
|
||||||
|
WriteToWS(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags)
|
bool acceptSignedPost(char const *data, int data_size, std::string username, int seq, std::string &errmsg, boost::uint32_t *flags)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user