#include #include #include #include "ScriptAPI.h" #include "../ScriptWorker.h" #pragma comment (lib, "Ws2_32.lib") #pragma once class CJSSocketWorker : public CScriptWorker { private: enum { TIMEOUT_MS = 1 }; struct JSSocketAddrInfo { char address[INET6_ADDRSTRLEN]; const char* family; unsigned short port; JSSocketAddrInfo() : address(""), family(""), port(0) { } }; struct BufferedWrite { size_t offset; std::vector data; duk_int_t callbackId; }; struct JSEmitDataEnv { char* data; size_t size; }; struct JSSocketQueue { CriticalSection cs; bool bConnectPending; bool bFullClosePending; bool bSendClosePending; bool bSendClosed; bool bRecvClosed; std::string connectHost; unsigned short connectPort; std::vector writes; JSSocketQueue() : bConnectPending(false), bFullClosePending(false), bSendClosePending(false), bSendClosed(false), bRecvClosed(false), connectHost(""), connectPort(0) { } }; SOCKET m_Socket; bool m_bWinsockOK; bool m_bAllowHalfOpen; JSSocketAddrInfo m_LocalAddress; JSSocketAddrInfo m_RemoteAddress; JSSocketQueue m_Queue; public: CJSSocketWorker(CScriptInstance* inst, void* objectHeapPtr, bool bAllowHalfOpen); virtual ~CJSSocketWorker(); bool Init(SOCKET sock); bool Init(const char* host, unsigned short port); void WorkerProc(); bool Write(const char* data, size_t length, duk_int_t callbackId, bool bEnd = false); //bool GetAddress(JSSocketAddrInfo& address); std::string GetLocalAddress(); unsigned short GetLocalPort(); std::string GetRemoteAddress(); unsigned short GetRemotePort(); const char* GetFamily(); private: bool ProcConnect(); void ProcSendData(); void ProcRecvData(); void UpdateAddresses(); void ClearAddress(); void ClearQueue(); void JSEmitConnect(); void JSEmitData(const char* data, size_t size); void JSEmitEnd(); void JSEmitClose(); void JSEmitDrain(); void JSEmitLookup(JSSocketAddrInfo& addr); void JSEmitError(const char* errMessage); static duk_idx_t CbArgs_EmitConnect(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitData(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitEnd(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitClose(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitDrain(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitLookup(duk_context* ctx, void* _env); static duk_idx_t CbArgs_EmitError(duk_context* ctx, void* _env); static duk_idx_t CbArgs_Write(duk_context* ctx, void* _env); };