{"id":3964,"date":"2023-06-30T13:11:59","date_gmt":"2023-06-30T11:11:59","guid":{"rendered":"https:\/\/cplugin.com\/?post_type=docs&#038;p=3964"},"modified":"2023-06-30T13:12:01","modified_gmt":"2023-06-30T11:12:01","password":"","slug":"web-sockets-signalr","status":"publish","type":"docs","link":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/","title":{"rendered":"Web Sockets (SignalR)"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">General information<\/h2>\n\n\n\n<p>SignalR makes possible to have two-way connectivity with web server to get\/send (streaming) data in real-time. For example, you can get quotes, margin updates of your MT4 clients, online users list, open orders at real time as it happens in MT4. Once you get subscribed to whatever you need you would get updates, no need to ask web server about new portion of data every time.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"WebSocketsgeneralinfromation-Quickexamples\">Quick examples<\/h2>\n\n\n\n<p>Here you can get working examples. Simply open source code of any page below and get client side code which demonstrates basic while negotiating with SignalR endpoint.<\/p>\n\n\n\n<p>This example shows data coming from server every second - current server time. No authentication needed.<a href=\"https:\/\/cloud.mywebapi.com\/DemoSignalR\/Test\"><br>https:\/\/cloud.MyWebAPI.com\/DemoSignalR\/Test<\/a>\u00a0- This example shows how you can get real-time date from WebAPI host server.\u00a0<a href=\"https:\/\/mywebapi.com\/DemoSignalR\/MT4\"><br><\/a><a href=\"https:\/\/cloud.mywebapi.com\/DemoSignalR\/MT4\">https:\/\/cloud.mywebapi.com\/DemoSignalR\/MT4<\/a>\u00a0-\u00a0Be aware, you need to adjust page source code (to make it work) to whatever you have for your installation (client_id, client_secret, tradeplatform_id, etc). Get page source, adjust settings and run the page.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<div class=\"ast-oembed-container \" style=\"height: 100%;\"><iframe title=\"MT4 + SignalR demonstration\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/NEuuyzY2r08?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe><\/div>\n<\/div><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"WebSocketsgeneralinfromation-Howtouse\">How to use<\/h2>\n\n\n\n<p>Add links to required libraries within your page's header:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"markup\" class=\"language-markup\">&lt;script src=\"https:\/\/ajax.aspnetcdn.com\/ajax\/jquery\/jquery-2.2.0.min.js\">&lt;\/script>\r\n&lt;script src=\"https:\/\/ajax.aspnetcdn.com\/ajax\/jquery.ui\/1.12.1\/jquery-ui.min.js\">&lt;\/script>\r\n&lt;script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/aspnet-signalr\/1.1.0\/signalr.js\">&lt;\/script><\/code><\/pre>\n\n\n\n<p>Then create connection to SignalR endpoint:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ access token obtained after authentication should be saved here\r\nvar access_token = '';\r\n \r\n\/\/ create connection\r\nconst connection = new signalR.HubConnectionBuilder()\r\n    .withUrl('@Context.Request.Scheme:\/\/@Context.Request.Host\/hubs\/mt4\/v1',\r\n        {\r\n            accessTokenFactory: () => {\r\n                \/\/show(\"AccessTokenProvider()\");\r\n                return access_token;\r\n            },\r\n            \/\/ let's skip negotiation and start right with websockets\r\n            transport: (signalR.HttpTransportType.WebSockets),\r\n            skipNegotiation: true\r\n        })\r\n    .configureLogging(signalR.LogLevel.Debug)\r\n    .build();<\/code><\/pre>\n\n\n\n<p>To connect just call:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">await connection.start();\r<\/code><\/pre>\n\n\n\n<p>You need an authentication token obtained from authentication server (auth.cplugin.net). Once you get a token, provide it to SignalR client through accessTokenFactory() function<code><\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"WebSocketsgeneralinfromation-Features\">Features<\/h2>\n\n\n\n<p>There are few hubs available to work with. Test and MT4. More details about each one you can find in corresponding section.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MT4 Hub<\/h2>\n\n\n\n<p>To step further, first of all, you have to be&nbsp;<a href=\"https:\/\/confluence.cplugin.com\/display\/SWP\/WebSockets+general+infromation\">Connected<\/a>&nbsp;to WebSockets endpoint. Then you can subscribe\/unsubscribe to\/form events and receive updates.<\/p>\n\n\n\n<p>This hub expose connectivity with MT4 server features. For example:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>get prices at real-time on your web page<\/li>\n\n\n\n<li>get clients' margin updates<\/li>\n\n\n\n<li>etc<\/li>\n<\/ul>\n\n\n\n<div class=\"wp-block-simple-alerts-for-gutenberg-alert-boxes sab-alert sab-alert-primary\" role=\"alert\">Assumed you are already authenticated, it needs so to call any function mentioned here.<br>Also assumed you have already connected to SignalR endpoint.<button type=\"button\" class=\"close\" data-dismiss=\"alert\" aria-label=\"Close\"><span aria-hidden=\"true\">\u00d7<\/span><\/button><\/div>\n\n\n\n<p>To get prices at real-time you can subscribe on interested symbols:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">connection\r\n    .invoke(\"SubscribeToTicks\", tradePlatform, \"EURUSD\")\r\n    .then((res) => { console.log(\"Subscribed to ticks (\" + this + \") : \" + res); })\r\n    .catch(err => console.error(err));<\/code><\/pre>\n\n\n\n<p>To determine with what server you are going to work you have to specify its identifier explicitly.<\/p>\n\n\n\n<p>To unsubscribe there is opposite function:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">connection\r\n    .invoke(\"UnsubscribeFromTicks\", tradePlatform, \"EURUSD\")\r\n    .then((res) => { console.log(\"Unsubscribed from ticks (EURUSD) : \" + res); })\r\n    .catch(err => console.error(err));<\/code><\/pre>\n\n\n\n<p>Once you get subscribed you start getting quotes immediately to your client side code:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">connection.on(\"onTick\", function(tradePlatform, tick) { your code here } )\r<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Interfaces<\/h2>\n\n\n\n<p>Up-to-date interface can always be downloaded from here: <a href=\"https:\/\/cloud.mywebapi.com\/GetTypeScriptInterface\">CPlugin.WebAPI.Realtime.ts (mywebapi.com)<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"typescript\" class=\"language-typescript\">import { HubConnection, IStreamResult } from \"@microsoft\/signalr\"\n\nexport class TestHub {\n    constructor(private connection: HubConnection) {\n    }\n\n    getServerTime(): Promise&lt;Date> {\n        return this.connection.invoke('GetServerTime');\n    }\n\n    ping(message: string): Promise&lt;Void> {\n        return this.connection.invoke('Ping', message);\n    }\n\n    registerCallbacks(implementation: ITestHubCallbacks) {\n        this.connection.on('Pong', (message) => implementation.pong(message));\n        this.connection.on('OnClock', (dt) => implementation.onClock(dt));\n    }\n\n    unregisterCallbacks(implementation: ITestHubCallbacks) {\n        this.connection.off('Pong', (message) => implementation.pong(message));\n        this.connection.off('OnClock', (dt) => implementation.onClock(dt));\n    }\n}\n\nexport interface ITestHubCallbacks {\n    pong(message: string): void;\n    onClock(dt: Date): void;\n}\n\nexport class MT4Hub {\n    constructor(private connection: HubConnection) {\n    }\n\n    connect(args: ConnectArgs): Promise&lt;boolean> {\n        return this.connection.invoke('Connect', args);\n    }\n\n    subscribeToTicks(args: SubscribeToTicksArgs): Promise&lt;void> {\n        return this.connection.invoke('SubscribeToTicks', args);\n    }\n\n    subscribeToAllTicks(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('SubscribeToAllTicks', args);\n    }\n\n    unsubscribeFromAllTicks(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('UnsubscribeFromAllTicks', args);\n    }\n\n    unsubscribeFromTicks(args: SubscribeToTicksArgs): Promise&lt;void> {\n        return this.connection.invoke('UnsubscribeFromTicks', args);\n    }\n\n    subscribeToSymbols(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('SubscribeToSymbols', args);\n    }\n\n    unsubscribeFromSymbols(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('UnsubscribeFromSymbols', args);\n    }\n\n    subscribeToOnlineUpdates(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('SubscribeToOnlineUpdates', args);\n    }\n\n    unsubscribeFromOnlineUpdates(args: TradePlatformId): Promise&lt;void> {\n        return this.connection.invoke('UnsubscribeFromOnlineUpdates', args);\n    }\n\n    streamTrades(args: TradePlatformId): IStreamResult&lt;TradeExEventPayload> {\n        return this.connection.stream('StreamTrades', args);\n    }\n\n    streamAllTicks(args: TradePlatformId): IStreamResult&lt;SymbolInfo> {\n        return this.connection.stream('StreamAllTicks', args);\n    }\n\n    streamMarginCallUpdates(args: TradePlatformId): IStreamResult&lt;MarginLevel> {\n        return this.connection.stream('StreamMarginCallUpdates', args);\n    }\n\n    streamUserUpdates(args: TradePlatformId): IStreamResult&lt;UserUpdate> {\n        return this.connection.stream('StreamUserUpdates', args);\n    }\n\n    registerCallbacks(implementation: IMT4HubCallbacks) {\n        this.connection.on('OnMT4ConnectionStatus', (data) => implementation.onMT4ConnectionStatus(data));\n        this.connection.on('OnTick', (data) => implementation.onTick(data));\n        this.connection.on('OnTicks', (data) => implementation.onTicks(data));\n        this.connection.on('OnTicksOHLC', (data) => implementation.onTicksOHLC(data));\n        this.connection.on('OnMarginUpdate', (data) => implementation.onMarginUpdate(data));\n        this.connection.on('OnSymbolUpdate', (data) => implementation.onSymbolUpdate(data));\n        this.connection.on('OnOnlineUpdate', (data) => implementation.onOnlineUpdate(data));\n        this.connection.on('OnDebug', (data) => implementation.onDebug(data));\n    }\n\n    unregisterCallbacks(implementation: IMT4HubCallbacks) {\n        this.connection.off('OnMT4ConnectionStatus', (data) => implementation.onMT4ConnectionStatus(data));\n        this.connection.off('OnTick', (data) => implementation.onTick(data));\n        this.connection.off('OnTicks', (data) => implementation.onTicks(data));\n        this.connection.off('OnTicksOHLC', (data) => implementation.onTicksOHLC(data));\n        this.connection.off('OnMarginUpdate', (data) => implementation.onMarginUpdate(data));\n        this.connection.off('OnSymbolUpdate', (data) => implementation.onSymbolUpdate(data));\n        this.connection.off('OnOnlineUpdate', (data) => implementation.onOnlineUpdate(data));\n        this.connection.off('OnDebug', (data) => implementation.onDebug(data));\n    }\n}\n\nexport interface IMT4HubCallbacks {\n    onMT4ConnectionStatus(data: MT4ConnectionStatusArgs): void;\n    onTick(data: TickArgs): void;\n    onTicks(data: TicksArgs): void;\n    onTicksOHLC(data: TicksOHLCArgs): void;\n    onMarginUpdate(data: MarginUpdateArgs): void;\n    onSymbolUpdate(data: SymbolUpdateArgs): void;\n    onOnlineUpdate(data: OnlineUpdateArgs): void;\n    onDebug(data: DebugArgs): void;\n}\n\nexport class MT5Hub {\n    constructor(private connection: HubConnection) {\n    }\n\n    connect(args: ConnectArgs2): Promise&lt;boolean> {\n        return this.connection.invoke('Connect', args);\n    }\n\n    registerCallbacks(implementation: IMT5HubCallbacks) {\n        this.connection.on('OnMT5ConnectionStatus', (tradePlatform, connected) => implementation.onMT5ConnectionStatus(tradePlatform, connected));\n    }\n\n    unregisterCallbacks(implementation: IMT5HubCallbacks) {\n        this.connection.off('OnMT5ConnectionStatus', (tradePlatform, connected) => implementation.onMT5ConnectionStatus(tradePlatform, connected));\n    }\n}\n\nexport interface IMT5HubCallbacks {\n    onMT5ConnectionStatus(tradePlatform: string, connected: boolean): void;\n}\n\nexport interface Void {\n}\n\nexport interface ConnectArgs {\n    tradePlatform: string;\n    \/** Timeout of pumping connection being UP and running. In milliseconds;\ndefault = 30 seconds; *\/\n    timeoutMs: number;\n}\n\nexport interface SubscribeToTicksArgs {\n    tradePlatform: string;\n    symbol: string | undefined;\n}\n\nexport interface TradePlatformId {\n    tradePlatform: string;\n}\n\nexport interface TradeExEventPayload extends TradeRecord {\n    \/** add - order opened, delete - order closed, Update - IF login==0 THEN order deleted ELSE order updated *\/\n    updateType: TransactionType;\n}\n\nexport enum TransactionType {\n    Add = \"Add\",\n    Delete = \"Delete\",\n    Update = \"Update\",\n    ChangeGrp = \"ChangeGrp\",\n}\n\nexport interface TradeRecord {\n    order: number;\n    login: number;\n    symbol: string | undefined;\n    openTime: Date;\n    closeTime: Date;\n    expiration: Date;\n    gatewayVolume: number;\n    gatewayVolumeLots: number;\n    digits: number;\n    volume: number;\n    volumeLots: number;\n    tradeRecordState: TradeRecordState;\n    openPrice: number;\n    sl: number;\n    tp: number;\n    commission: number;\n    commissionAgent: number;\n    convReserv: string | undefined;\n    tradeRecordReason: TradeRecordReason;\n    storage: number;\n    closePrice: number;\n    profit: number;\n    taxes: number;\n    magic: number;\n    comment: string | undefined;\n    gatewayOrder: number;\n    activationType: ActivationType;\n    gatewayOpenPrice: number;\n    gatewayClosePrice: number;\n    marginRate: number;\n    timeStamp: Date;\n    apiData: number[] | undefined;\n    convRates: number[] | undefined;\n    tradeCommand: TradeCommand;\n}\n\nexport enum TradeRecordState {\n    OpenNormal = \"OpenNormal\",\n    OpenRemand = \"OpenRemand\",\n    OpenRestored = \"OpenRestored\",\n    ClosedNormal = \"ClosedNormal\",\n    ClosedPart = \"ClosedPart\",\n    ClosedBy = \"ClosedBy\",\n    Deleted = \"Deleted\",\n}\n\nexport enum TradeRecordReason {\n    Client = \"Client\",\n    Expert = \"Expert\",\n    Dealer = \"Dealer\",\n    Signal = \"Signal\",\n    Gateway = \"Gateway\",\n    Mobile = \"Mobile\",\n    Web = \"Web\",\n    API = \"API\",\n}\n\nexport enum ActivationType {\n    None = \"None\",\n    SL = \"SL\",\n    TP = \"TP\",\n    Pending = \"Pending\",\n    Stopout = \"Stopout\",\n    StopOutRollback = \"StopOutRollback\",\n    PendingRollback = \"PendingRollback\",\n    TPRollback = \"TPRollback\",\n    SLRollback = \"SLRollback\",\n}\n\nexport enum TradeCommand {\n    Buy = \"Buy\",\n    Sell = \"Sell\",\n    BuyLimit = \"BuyLimit\",\n    SellLimit = \"SellLimit\",\n    BuyStop = \"BuyStop\",\n    SellStop = \"SellStop\",\n    Balance = \"Balance\",\n    Credit = \"Credit\",\n}\n\nexport interface SymbolInfo {\n    lastTime: Date | undefined;\n    visible: boolean;\n    symbol: string | undefined;\n    digits: number;\n    count: number;\n    type: number;\n    point: number;\n    spread: number;\n    spreadBalance: number;\n    direction: SymbolPriceDirection;\n    updateFlag: number;\n    bid: number;\n    ask: number;\n    high: number;\n    low: number;\n    commission: number;\n    commType: CommissionType;\n}\n\nexport enum SymbolPriceDirection {\n    Up = \"Up\",\n    Down = \"Down\",\n    None = \"None\",\n}\n\nexport enum CommissionType {\n    Money = \"Money\",\n    Pips = \"Pips\",\n    Percent = \"Percent\",\n}\n\nexport interface MarginLevel {\n    group: string | undefined;\n    login: number;\n    leverage: number;\n    updated: number;\n    balance: number;\n    equity: number;\n    volume: number;\n    margin: number;\n    free: number;\n    level: number;\n    controllingType: MarginControllingType;\n    levelType: MarginLevelType;\n}\n\nexport enum MarginControllingType {\n    Percent = \"Percent\",\n    Currency = \"Currency\",\n}\n\nexport enum MarginLevelType {\n    Ok = \"Ok\",\n    MarginCall = \"MarginCall\",\n    StopOut = \"StopOut\",\n}\n\nexport interface UserUpdate {\n    type: TransactionType;\n    user: UserRecord | undefined;\n}\n\nexport interface UserRecord {\n    regDate: Date;\n    lastDate: Date;\n    timeStamp: Date;\n    login: number;\n    group: string | undefined;\n    password: string | undefined;\n    enable: number;\n    enableChangePassword: number;\n    enableReadOnly: number;\n    enableOTP: number;\n    enableReserved: number[] | undefined;\n    passwordInvestor: string | undefined;\n    passwordPhone: string | undefined;\n    name: string | undefined;\n    country: string | undefined;\n    city: string | undefined;\n    state: string | undefined;\n    zipCode: string | undefined;\n    address: string | undefined;\n    leadSource: string | undefined;\n    phone: string | undefined;\n    email: string | undefined;\n    comment: string | undefined;\n    id: string | undefined;\n    status: string | undefined;\n    leverage: number;\n    agentAccount: number;\n    lastIP: number;\n    balance: number;\n    prevMonthBalance: number;\n    prevBalance: number;\n    credit: number;\n    interestRate: number;\n    taxes: number;\n    prevMonthEquity: number;\n    prevEquity: number;\n    reserved2: number[] | undefined;\n    otpSecret: string | undefined;\n    secureReserved: string | undefined;\n    sendReports: number;\n    mqid: number;\n    userColor: number;\n    unused: string | undefined;\n    apiData: string | undefined;\n}\n\nexport interface MT4ConnectionStatusArgs extends TradePlatformId {\n    connected: boolean;\n}\n\nexport interface TickArgs extends TradePlatformId {\n    tick: Tick | undefined;\n}\n\nexport interface Tick {\n    symbol: string | undefined;\n    bid: number;\n    ask: number;\n    lastTime: Date | undefined;\n}\n\nexport interface TicksArgs extends TradePlatformId {\n    ticks: TickArgs[] | undefined;\n}\n\nexport interface TicksOHLCArgs extends TradePlatformId {\n    ticks: OHLCS[] | undefined;\n}\n\nexport interface OHLCS {\n    \/** Priced being at the beginning of interval *\/\n    open: BidAsk | undefined;\n    \/** highest ever bid and ask, calculated separately. *\/\n    maximum: BidAsk | undefined;\n    \/** lowest ever bid and ask, calculated separately. *\/\n    minimum: BidAsk | undefined;\n    \/** Priced being at the end of interval *\/\n    close: BidAsk | undefined;\n    symbol: string | undefined;\n    lastTime: Date | undefined;\n    \/** number of ticks before groupping *\/\n    volume: number;\n}\n\nexport interface BidAsk {\n    bid: number;\n    ask: number;\n}\n\nexport interface MarginUpdateArgs extends TradePlatformId {\n    margins: MarginLevel[] | undefined;\n}\n\nexport interface SymbolUpdateArgs extends TradePlatformId {\n    type: TransactionType;\n    symbol: ConSymbol | undefined;\n}\n\nexport interface ConSymbol {\n    symbol: string | undefined;\n    description: string | undefined;\n    source: string | undefined;\n    currency: string | undefined;\n    type: number;\n    digits: number;\n    tradeMode: TradeMode;\n    backgroundColor: number;\n    count: number;\n    countOriginal: number;\n    realtime: number;\n    starting: Date;\n    expiration: Date;\n    sessions: ConSessions[] | undefined;\n    profitCalculationMode: ProfitCalculationMode;\n    profitReserved: number;\n    filter: number;\n    filterCounter: number;\n    filterLimit: number;\n    filterSmoothing: number;\n    filterReserved: number;\n    logging: number;\n    spread: number;\n    spreadBalance: number;\n    symbolExecMode: SymbolExecMode;\n    swapEnable: number;\n    swapType: SwapType;\n    swapLong: number;\n    swapShort: number;\n    swapRollover3Days: number;\n    contractSize: number;\n    tickValue: number;\n    tickSize: number;\n    stopsLevel: number;\n    gtcMode: GTCMode;\n    marginCalculationMode: MarginCalculationMode;\n    marginInitial: number;\n    marginMaintenance: number;\n    marginHedged: number;\n    marginDivider: number;\n    percentage: number;\n    point: number;\n    multiply: number;\n    bidTickValue: number;\n    askTickValue: number;\n    longOnly: number;\n    instantMaxVolume: number;\n    marginCurrency: string | undefined;\n    freezeLevel: number;\n    marginHedgedStrong: number;\n    valueDate: Date;\n    quotesDelay: number;\n    swapOpenPrice: number;\n    swapVariationMargin: number;\n}\n\nexport enum TradeMode {\n    No = \"No\",\n    Close = \"Close\",\n    Full = \"Full\",\n}\n\nexport interface ConSessions {\n    quoteOvernight: number;\n    tradeOvernight: number;\n    quote: ConSession[] | undefined;\n    trade: ConSession[] | undefined;\n}\n\nexport interface ConSession {\n    openHour: number;\n    openMin: number;\n    closeHour: number;\n    closeMin: number;\n    align: number[] | undefined;\n}\n\nexport enum ProfitCalculationMode {\n    Forex = \"Forex\",\n    CFD = \"CFD\",\n    Futures = \"Futures\",\n}\n\nexport enum SymbolExecMode {\n    Request = \"Request\",\n    Instant = \"Instant\",\n    Market = \"Market\",\n}\n\nexport enum SwapType {\n    Points = \"Points\",\n    Dollars = \"Dollars\",\n    Interest = \"Interest\",\n    MarginCurrency = \"MarginCurrency\",\n}\n\nexport enum GTCMode {\n    Daily = \"Daily\",\n    GTC = \"GTC\",\n    DailyNoStops = \"DailyNoStops\",\n}\n\nexport enum MarginCalculationMode {\n    Forex = \"Forex\",\n    CFD = \"CFD\",\n    Futures = \"Futures\",\n    CFDIndex = \"CFDIndex\",\n    CFDLeverage = \"CFDLeverage\",\n}\n\nexport interface OnlineUpdateArgs extends TradePlatformId {\n    type: TransactionType;\n    login: number;\n}\n\nexport interface DebugArgs extends TradePlatformId {\n    category: string | undefined;\n    message: string | undefined;\n    data: any | undefined;\n}\n\nexport interface ConnectArgs2 extends TradePlatformId {\n    \/** Timeout of pumping connection being UP and running. In milliseconds;\ndefault = 30 seconds; *\/\n    timeoutMs: number;\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Test hub<\/h2>\n\n\n\n<p>This hub created to let you get general ideas working with SignalR. There are nothing special. It does not even require you to be authenticated.<\/p>\n\n\n\n<p>To get fully working code navigate to&nbsp;<a href=\"https:\/\/cloud.mywebapi.com\/DemoSignalR\/Test\">https:\/\/cloud.myWebAPI.com\/DemoSignalR\/Test<\/a>&nbsp;and get page source code.<\/p>\n\n\n\n<p>To access hub you can get a link to it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">const connection = new signalR.HubConnectionBuilder()\r\n    .withUrl('https:\/\/cloud.myWebAPI.com\/hubs\/test\/v1')\r\n    .configureLogging(signalR.LogLevel.Debug)\r\n    .build();<\/code><\/pre>\n\n\n\n<p>Method 'ping(string)'<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ You can pass any string to this method:\r\n\r\n\nconnection\r\n    .invoke(\"Ping\", \"test message\")\r\n    .then(() => console.log(\"Ping request sent\"))\r\n    .catch(err => console.error(err));<\/code><\/pre>\n\n\n\n<p>Server will be returned back through client side callback 'pong' exactly the same you have sent there:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">connection.on(\"pong\",\r\n    function(msg) {\r\n        console.log(\"pong: \" + msg);\r\n    });<\/code><\/pre>\n\n\n\n<p>Get server time<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">\/\/ Each second server will send its time through client side callback as of:\r\n\r\nconnection.on(\"onClock\",\r\n    function(clock) {\r\n        console.log(clock);\r\n    });<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>General information SignalR makes possible to have two-way connectivity with web server to get\/send (streaming) data in real-time. For example, you can get quotes, margin updates of your MT4 clients, online users list, open orders at real time as it happens in MT4. Once you get subscribed to whatever you need you would get updates, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"doc_category":[96],"doc_tag":[],"class_list":["post-3964","docs","type-docs","status-publish","hentry","doc_category-webapi"],"year_month":"2026-06","word_count":2000,"total_views":0,"reactions":{"happy":0,"normal":0,"sad":0},"author_info":{"name":"Vladislav Sorokin","author_nicename":"cplugin","author_url":"https:\/\/cplugin.com\/blog\/author\/cplugin\/"},"doc_category_info":[{"term_name":"WebAPI","term_url":"https:\/\/cplugin.com\/docs-category\/webapi\/"}],"doc_tag_info":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v25.7 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Web Sockets (SignalR) - CPlugin<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Web Sockets (SignalR) - CPlugin\" \/>\n<meta property=\"og:description\" content=\"General information SignalR makes possible to have two-way connectivity with web server to get\/send (streaming) data in real-time. For example, you can get quotes, margin updates of your MT4 clients, online users list, open orders at real time as it happens in MT4. Once you get subscribed to whatever you need you would get updates, [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/\" \/>\n<meta property=\"og:site_name\" content=\"CPlugin\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/cplugin\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-30T11:12:01+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@CPlugin_com\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"9 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/\",\"url\":\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/\",\"name\":\"Web Sockets (SignalR) - CPlugin\",\"isPartOf\":{\"@id\":\"https:\/\/cplugin.com\/#website\"},\"datePublished\":\"2023-06-30T11:11:59+00:00\",\"dateModified\":\"2023-06-30T11:12:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/cplugin.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Docs\",\"item\":\"https:\/\/cplugin.com\/wiki\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Web Sockets (SignalR)\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/cplugin.com\/#website\",\"url\":\"https:\/\/cplugin.com\/\",\"name\":\"CPlugin\",\"description\":\"CPlugin offers software and services to Forex brokers who use MetaQuotes MetaTrader 4 and 5 which are most advanced and reliable trading platforms.\",\"publisher\":{\"@id\":\"https:\/\/cplugin.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/cplugin.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/cplugin.com\/#organization\",\"name\":\"CPlugin Ltd.\",\"url\":\"https:\/\/cplugin.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/cplugin.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.cplugin.com\/wp-content\/uploads\/2021\/07\/CPlugin-logo-1.png\",\"contentUrl\":\"https:\/\/www.cplugin.com\/wp-content\/uploads\/2021\/07\/CPlugin-logo-1.png\",\"width\":1823,\"height\":677,\"caption\":\"CPlugin Ltd.\"},\"image\":{\"@id\":\"https:\/\/cplugin.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/cplugin\",\"https:\/\/x.com\/CPlugin_com\",\"https:\/\/www.linkedin.com\/company\/cplugin\",\"https:\/\/www.youtube.com\/c\/CPlugin_com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Web Sockets (SignalR) - CPlugin","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/","og_locale":"en_US","og_type":"article","og_title":"Web Sockets (SignalR) - CPlugin","og_description":"General information SignalR makes possible to have two-way connectivity with web server to get\/send (streaming) data in real-time. For example, you can get quotes, margin updates of your MT4 clients, online users list, open orders at real time as it happens in MT4. Once you get subscribed to whatever you need you would get updates, [&hellip;]","og_url":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/","og_site_name":"CPlugin","article_publisher":"https:\/\/www.facebook.com\/cplugin","article_modified_time":"2023-06-30T11:12:01+00:00","twitter_card":"summary_large_image","twitter_site":"@CPlugin_com","twitter_misc":{"Est. reading time":"9 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/","url":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/","name":"Web Sockets (SignalR) - CPlugin","isPartOf":{"@id":"https:\/\/cplugin.com\/#website"},"datePublished":"2023-06-30T11:11:59+00:00","dateModified":"2023-06-30T11:12:01+00:00","breadcrumb":{"@id":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/cplugin.com\/docs\/webapi\/web-sockets-signalr\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/cplugin.com\/"},{"@type":"ListItem","position":2,"name":"Docs","item":"https:\/\/cplugin.com\/wiki\/"},{"@type":"ListItem","position":3,"name":"Web Sockets (SignalR)"}]},{"@type":"WebSite","@id":"https:\/\/cplugin.com\/#website","url":"https:\/\/cplugin.com\/","name":"CPlugin","description":"CPlugin offers software and services to Forex brokers who use MetaQuotes MetaTrader 4 and 5 which are most advanced and reliable trading platforms.","publisher":{"@id":"https:\/\/cplugin.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/cplugin.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/cplugin.com\/#organization","name":"CPlugin Ltd.","url":"https:\/\/cplugin.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/cplugin.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.cplugin.com\/wp-content\/uploads\/2021\/07\/CPlugin-logo-1.png","contentUrl":"https:\/\/www.cplugin.com\/wp-content\/uploads\/2021\/07\/CPlugin-logo-1.png","width":1823,"height":677,"caption":"CPlugin Ltd."},"image":{"@id":"https:\/\/cplugin.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/cplugin","https:\/\/x.com\/CPlugin_com","https:\/\/www.linkedin.com\/company\/cplugin","https:\/\/www.youtube.com\/c\/CPlugin_com"]}]}},"_links":{"self":[{"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/docs\/3964","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/docs"}],"about":[{"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/types\/docs"}],"author":[{"embeddable":true,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/comments?post=3964"}],"version-history":[{"count":1,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/docs\/3964\/revisions"}],"predecessor-version":[{"id":3965,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/docs\/3964\/revisions\/3965"}],"wp:attachment":[{"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/media?parent=3964"}],"wp:term":[{"taxonomy":"doc_category","embeddable":true,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/doc_category?post=3964"},{"taxonomy":"doc_tag","embeddable":true,"href":"https:\/\/cplugin.com\/wp-json\/wp\/v2\/doc_tag?post=3964"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}