CSTA SignalR client API
tip
It's recommended to use the SignalR API for new development, if your programming language support SignalR.
Clients​
SignalR is a modern two-way communication that support multiple transport technologies, ideally using WebSocket. A thorough guide can be found in Microsoft's own documentation here.
Technology | Package |
---|---|
.NET | Microsoft.AspNetCore.SignalR.Client |
JavaScript | @microsoft/signalr |
How to use​
tip
The SignalR client support JSON requests, responses and events. They follow the CSTA format in the ECMA-323 CSTA Standard, but are supported in JSON instead of XML.
- SignalR hub: Instantiate a client class and connect
- Authentication: Login using CSTA StartApplicationSession request
- Call other CSTA methods on the client to interact with your hosted pbx
.NET sample client​
The C# sample client is written for .NET Core 6, but should be backwards compatible to older ASP.NET Core versions.
using Microsoft.AspNetCore.SignalR.Client;
using Microsoft.Extensions.Options;
using Unitel.Csta.Standard.Events;
using Unitel.Csta.Standard.Requests;
namespace Unitel.Csta.SignalR.TestClient
{
public class SignalRClient
{
private readonly ILogger<SignalRClient> _logger;
private readonly string _uri;
private HubConnection _connection;
delegate void NotifyClientConnectionDelegate<T>(T message);
public event NotifyClientConnectionDelegate<ConnectionClearedEvent> NotifyOnConnectionClearedEvent;
public event NotifyClientConnectionDelegate<DeliveredEvent> NotifyOnDeliveredEvent;
public event NotifyClientConnectionDelegate<EstablishedEvent> NotifyOnEstablishedEvent;
public event NotifyClientSignalRClosed NotifySignalRClosed;
public SignalRClient(ILogger<SignalRClient> logger)
{
_logger = logger;
_uri = "GATEWAY_API" + "/csta";
_connection = new HubConnectionBuilder().WithUrl(new Uri(_uri)).Build();
}
public async Task Start()
{
SetupSignalRConnectionEventListeners();
SetupCstaEventListeners();
try
{
_logger.LogDebug($"SignalR client connecting...");
if (_connection.State == HubConnectionState.Disconnected)
{
await _connection.StartAsync();
}
else
{
_logger.LogDebug($"SignalR client already connected.");
}
}
catch (Exception e)
{
_logger.LogError(e, $"Failed to start SignalR client, {e.Message}");
NotifySignalRClosed();
throw;
}
}
public async Task Stop()
{
try
{
_logger.LogDebug($"SignalR client shutting down...");
if (_connection != null)
{
await _connection.StopAsync();
await _connection.DisposeAsync();
_connection = null;
}
}
catch (Exception e)
{
_logger.LogError(e, $"Failed to stop SignalR client, {e.Message}");
throw;
}
}
public async Task<StartApplicationSessionPosResponse> StartApplicationSession(StartApplicationSession request)
{
return await _connection.InvokeAsync<StartApplicationSessionPosResponse>("StartApplicationSession", request);
}
public async Task<MonitorStartResponse> MonitorStart(MonitorStart request)
{
return await _connection.InvokeAsync<MonitorStartResponse>("MonitorStart", request);
}
public async Task<MakeCallResponse> MakeCall(MakeCall request)
{
return await _connection.InvokeAsync<MakeCallResponse>("MakeCall", request);
}
public async Task<ClearConnectionResponse> ClearConnection(ClearConnection request)
{
return await _connection.InvokeAsync<ClearConnectionResponse>("ClearConnection", request);
}
private void SetupCstaEventListeners()
{
_connection.On<ConnectionClearedEvent>("ConnectionCleared", (message) =>
{
NotifyOnConnectionClearedEvent(message);
_logger.LogDebug($"ConnectionClearedEvent");
});
_connection.On<DeliveredEvent>("Delivered", (message) =>
{
NotifyOnDeliveredEvent(message);
_logger.LogDebug($"DeliveredEvent");
});
_connection.On<EstablishedEvent>("Established", (message) =>
{
NotifyOnEstablishedEvent(message);
_logger.LogDebug($"EstablishedEvent");
});
}
private void SetupSignalRConnectionEventListeners()
{
_connection.Closed += error =>
{
_logger.LogInformation("SignalR Client connection closed.");
NotifySignalRClosed();
return Task.CompletedTask;
};
}
}
}
Use Case​
class Test
{
public void ExecuteTest()
{
var client = new CstaClient();
client.NotifySignalRClosed += () => { _logger.LogInformation("Connection closed"); };
client.NotifyOnEvent += (e) => { _logger.LogInformation("Event received"); };
await client.Start();
await client.StartApplicationSession(CreateStartApplicationSessionRequest());
await client.MakeCall(CreateMakeCallRequest("222", "333"))
}
private StartApplicationSessionRequest CreateStartApplicationSessionRequest()
{
return new StartApplicationSessionRequest
{
ApplicationInfo = new ApplicationInfo
{
ApplicationSpecificInfo = new ApplicationSpecificInfo
{
UserId = "username",
Password = "password",
PbxDomain = "pbxDomain"
}
}
};
}
private MakeCallRequest CreateMakeCallRequest(string callerId, string calleeId)
{
return new MakeCallRequest
{
CallingDevice = callerId,
CalledDirectoryNumber = calleeId,
PrivateData = new RequestResponsePrivateData
{
RequestId = Guid.NewGuid().ToString(),
}
};
}
}
TypeScript ES6 sample client​
class CstaClient {
connection!: HubConnection;
async connect(): Promise<void> {
this.connection = new HubConnectionBuilder().withUrl(GATEWAY_API).build();
await this.connection.start();
console.log("Connected to csta gateway");
}
async disconnect(): Promise<void> {
await this.connection.stop();
}
async startApplicationSession(username: string, password: string, pbxDomain: string) {
const response = await this.connection.invoke("StartApplicationSession", {
applicationInfo: {
applicationSpecificInfo: {
"vendorData:userID": username,
"vendorData:password": password,
"vendorData:pbxDomain": pbxDomain,
},
},
requestedSessionDuration: 120,
});
console.log(response);
}
async monitorStart(trunkId: string, deviceId: string): Promise<void> {
const response = await this.connection.invoke("MonitorStart", {
monitorObject: { deviceObject: "u-" + trunkId + "-" + deviceId },
});
console.log("MonitorStart response", response);
}
async makeCall(callingDevice: string, calledDirectoryNumber: string): Promise<void> {
const response = await this.connection.invoke("MakeCall", {
callingDevice: callingDevice,
calledDirectoryNumber: calledDirectoryNumber,
});
console.log("MakeCall Response", response);
}
async clearConnection(callId: string): Promise<void> {
const response = await this.connection.invoke("ClearConnection", {
connectionToBeCleared: {
callId: callId,
},
privateData: {
requestId: "request-clearconnection-" + callId,
},
});
console.log("ClearConnection Response", response);
}
subscribeToEvents(): void {
this.connection.on("Delivered", (e: DeliveredEvent) => {
console.log("Delivered", e);
});
this.connection.on("Established", (e: EstablishedEvent) => {
console.log("Established", e);
});
this.connection.on("ConnectionCleared", (e: ConnectionClearedEvent) => {
console.log("ConnectionCleared", e);
});
}
}
export default new CstaClient();
Use Case​
const client = new CstaClient();
await client.connect();
await client.startApplicationSession("username", "password", "pbxDomain");
await client.makeCall("22334455", "333");
Get access to uni-tel CSTA SignalR API​
If you want to know more, feel free to contact us here. The contact form is in Danish only, but inquiries in English are most welcome.