Use Channels
Use channels to create connections and send or receive messages. Channels are textual identifiers that you can link between clients, connections, or messages. You don't need to "create" or "destroy" channels. A Client instance lets you join a channel by calling client.Join
, and then specifying the name of the channel and the token authorizing you to join that channel.
Channels are flexible. Use them in many ways: as individual channels, as notification subscriptions, or any other things your app might need.
Note
About the code examples on this page:
- For .NET MAUI and Unity, use the C# code.
- For macOS, use the iOS code.
Join a New Channel
To join a channel, you must generate a token. The syntax for generating a token is similar to generating a token when registering with Gateway, but slightly different. Specify an array of FM.LiveSwitch.ChannelClaim
and call the GenerateClientJoinToken
method of the FM.LiveSwitch.Token
class to generate the token.
The following example shows how to generate a token to join a new channel on the client side. For your production environment, always generate an authorization token on the server side.
Note
Channel IDs aren't case-sensitive. For example, my-awesome-channel-123
and My-Awesome-Channel-123
are the same channel.
var applicationId = "my-app";
var userId = "my-name";
var deviceId = "00000000-0000-0000-0000-000000000000";
var channelId = "99999999-9999-9999-9999-999999999999";
var client = new FM.LiveSwitch.Client(...);
string token = FM.LiveSwitch.Token.GenerateClientJoinToken(
applicationId,
client.UserId,
client.DeviceId,
client.Id,
new FM.LiveSwitch.ChannelClaim(channelId),
"--replaceThisWithYourOwnSharedSecret--"
);
See also:
String applicationId = "my-app";
String userId = "my-name";
String deviceId = "00000000-0000-0000-0000-000000000000";
String channelId = "99999999-9999-9999-9999-999999999999";
fm.liveswitch.Client client = new fm.liveswitch.Client(...);
String token = fm.liveswitch.Token.generateClientJoinToken(
applicationId,
client.getUserId(),
client.getDeviceId(),
client.getId(),
new fm.liveswitch.ChannelClaim[] { channelId },
"--replaceThisWithYourOwnSharedSecret--"
);
See also:
var applicationId = "my-app"
var userId = "my-name"
var deviceId = "00000000-0000-0000-0000-000000000000"
var channelId = "99999999-9999-9999-9999-999999999999"
var client = FMLiveSwitchClient(...)
var token:String = FMLiveSwitchToken.generateClientJoinToken(
applicationId: applicationId,
userId: client.userId(),
deviceId: client.deviceId(),
clientId: client.id(),
channelClaims: FMLiveSwitchChannelClaim(channelId: channelId),
sharedSecret: "--replaceThisWithYourOwnSharedSecret--"
)
See also:
var applicationId = "my-app";
var userId = "my-name";
var deviceId = "00000000-0000-0000-000000000000";
var channelId = "99999999-9999-9999-9999-999999999999";
var client = new fm.liveswitch.Client(...);
var token = fm.liveswitch.Token.generateClientJoinToken(
applicationId,
client.getUserId(),
client.getDeviceId(),
client.getId(),
new fm.liveswitch.ChannelClaim(channelId),
"--replaceThisWithYourOwnSharedSecret--"
);
See also:
Once you have created a token, validate the token with the LiveSwitch Gateway. To do this, invoke the Join
method of your FM.LiveSwitch.Client
instance using the token and a channel ID. The channel ID that you specify must match the ID of the ChannelClaim
instance that you used to create the token. The Join
method returns a promise. You can inspect the promise to see whether the client has successfully joined the channel.
client.Join(channelId, token).Then((FM.LiveSwitch.Channel channel) => {
Console.WriteLine("successfully joined channel");
}).Fail((Exception ex) => {
Console.WriteLine("failed to join channel");
});
client.join(channelId, token).then((fm.liveswitch.Channel channel) -> {
System.out.println("successfully joined channel");
}).fail((Exception ex) -> {
System.out.println("failed to join channel");
});
client.join(channelId: channelId, token: token).then(resolveAction: {
(FMLiveSwitchChannel channel) in
print("successfully joined channel")
})
.fail(rejectAction: {
(NSException ex) in
print("failed to join channel")
})
client
.join(channelId, token)
.then(function (channel) {
console.log('successfully joined channel')
})
.fail(function (ex) {
console.log('failed to join channel')
})
Send Messages
You can send text messages like chat, notifications about user events, syncing data, and so on. You can also include tags in the message with metadata information about the sender.
You can send text messages to everyone, specific users, or specific devices.
// To everyone
_Channel.OnMessage += (remoteClientInfo, message) => {}
_Channel.SendMessage(text)
// To a specific user
_Channel.OnUserMessage += (remoteClientInfo, message) => {}
_Channel.SendUserMessage(userId, text)
// To a specific device
_Channel.OnDeviceMessage ++ (senderClientInfo, message) => {}
_Channel.SendDeviceMessage(userId, deviceId, text)
// To everyone
channel.addOnMessage((senderClientInfo, message) -> {});
channel.sendMessage(text);
// To a specific user
channel.addOnUserMessage((senderClientInfo, message) -> {});
channel.sendUserMessage(userId, text);
// To a specific device
channel.addOnDeviceMessage((senderClientInfo, message) -> {});
channel.sendDeviceMessage(userId, deviceId, text);
// To everyone
self._channel?.addOnMessage({ (obj0: FMLiveSwitchClientInfo?, obj1: String?) in
let senderClientInfo = obj as! FMLiveSwitchClientInfo;
let message = obj1 as! String;
})
self._channel?.sendMessage(text);
// To a specific user
self._channel?.addOnUserMessage({ (obj0: FMLiveSwitchClientInfo?, obj1: String?) in
let senderClientInfo = obj as! FMLiveSwitchClientInfo;
let message = obj1 as! String;
})
self._channel?.sendUserMessage(userId, text);
// To a specific device
self._channel?.addOnDeviceMessage({ (obj0: FMLiveSwitchClientInfo?, obj1: String?) in
let senderClientInfo = obj as! FMLiveSwitchClientInfo;
let message = obj1 as! String;
})
self._channel.sendDeviceMessage(userId, deviceId, text)
// To everyone
channel.addOnMessage((senderClientInfo, message) => {})
channel.sendMessage(text))
// To a specific user
channel.addOnUserMessage((senderClientInfo, message) => {})
channel.sendUserMessage(userId, text))
// To a specific device
channel.addOnDeviceMessage((senderClientInfo, message) => {})
channel.sendDeviceMessage(userId, deviceId, text))
Leave a Channel
A client might want to leave a channel when a video conference ends. To leave a channel, call the Leave
method of the FM.LiveSwitch.Client
instance and use the channelId
. The Leave
method returns a promise. You can inspect the promise to see whether the client has successfully left the channel.
client.Leave(channelId).Then((FM.LiveSwitch.Channel channel) => {
Console.WriteLine("left the channel");
}).Fail((Exception ex) => {
Console.WriteLine("failed to leave the channel");
});
client.leave(channelId).then((fm.liveswitch.Channel channel) -> {
System.out.println("left the channel");
}).fail((Exception ex) -> {
System.out.println("failed to leave the channel");
});
client.leave(channelId: channelId).then(resolveAction: {
(FMLiveSwitchChannel channel) in
print("left the channel")
})
.fail(rejectAction: {
(NSException ex) in
print("failed to leave the channel")
})
client
.leave(channelId)
.then(function (channel) {
console.log('left the channel')
})
.fail(function (ex) {
console.log('failed to leave the channel')
})
If you leave a channel, the authorization token you used for this channel is now invalid. You must generate a new token to join the same channel.
In your app, you can join and leave a channel at any time.
Manage Remote Client in a Channel
You can use RemoteClientInfo
of the Channel
object to manage remote clients in a channel. Once you have joined a channel, use the following mechanisms to access remote client data:
- Existing clients:
channel.getRemoteClientInfos
- Joining clients:
channel.addOnRemoteClientJoin
- Leaving clients:
channel.addOnRemoteClientLeave
You can use metadata, like the tag or user ID, on the RemoteClientInfo
object to identify a particular user.
// initial state
var remoteClientInfo = _Channel.GetRemoteClientInfo(userId);
// changes
_Channel.OnRemoteClientJoin += (remoteClientInfo) => {};
_Channel.OnRemoteClientLeave += (remoteClientInfo) => {};
// initial state
var remoteClientInfos = channel.getRemoteClientInfos();
for (ClientInfo remoteClientInfo: remoteClientInfos)
{
Log.info(remoteClientInfo.getUserId() + " is already in (" + remoteClientInfo.getId() + ").");
}
// changes
channel.addOnRemoteClientJoin(remoteClientInfo -> {});
channel.addOnRemoteClientLeave(remoteClientInfo -> {});
// initial state
let remoteClientInfo = self._channel?.getRemoteClientInfoWithClientId(clientId);
// changes
self._channel?.addOnRemoteClientJoin({ [weak self] (obj: Any!) in
let remoteClientInfo = obj as! FMLiveSwitchClientInfo
self?.onMessageReceived?.invoke(withP1: remoteClientInfo.userAlias() ?? "", p2: "Joined")
FMLiveSwitchLog.info(withMessage: "Remote client joined the channel (client ID: \(String(describing: remoteClientInfo.id())), device ID: \(String(describing: remoteClientInfo.deviceId())), user ID: \(String(describing: remoteClientInfo.userId()))).");
})
self._channel?.addOnRemoteClientLeave({ [weak self] (obj: Any!) in
let remoteClientInfo = obj as! FMLiveSwitchClientInfo
self?.onMessageReceived?.invoke(withP1: remoteClientInfo.userAlias() ?? "", p2: "Left")
FMLiveSwitchLog.info(withMessage: "Remote client left the channel (client ID: \(String(describing: remoteClientInfo.id())), device ID: \(String(describing: remoteClientInfo.deviceId())), user ID: \(String(describing: remoteClientInfo.userId())).");
})
// initial state
channel.getRemoteClientInfos().forEach(remoteClientInfo => {
console.info(
remoteClientInfo.getUserId() +
' is already in (' +
remoteClientInfo.getId() +
').'
)
})
// changes
channel.addOnRemoteClientJoin(remoteClientInfo => {
console.info(
remoteClientInfo.getUserId() + ' joined (' + remoteClientInfo.getId() + ').'
)
})
channel.addOnRemoteClientLeave(remoteClientInfo => {
console.info(
remoteClientInfo.getUserId() + ' left (' + remoteClientInfo.getId() + ').'
)
})
See also:
Remove Clients From a Channel
The Channel
object has a kickClient
method. In your app, you can remove clients out of a channel. To remove a client, your channel claim must have the CanKick
privilege.
The following code example shows how to:
- Create a channel claim and set the
CanKick
privilege to the channel claim.
- Allow the client to remove other users in this channel.
var kickingChannelExampleClaim = new FM.LiveSwitch.ChannelClaim("KickChannel") {
CanKick = true
};
var claims = new ChannelClaim[] {
kickingChannelExampleClaim
};
See also:
final ChannelClaim kickingChannelExampleClaim = new fm.liveswitch.ChannelClaim("KickChannel");
kickingChannelExampleClaim.setCanKick(true);
final ChannelClaim[] claims = new ChannelClaim[] {
kickingChannelExampleClaim
};
See also:
let kickingChannelExampleClaim = FMLiveSwitchChannelClaim(ID: "KickChannel")
kickingChannelExampleClaim?.setCanKick(true);
let claims = [kickingChannelExampleClaim]
See also:
let kickingChannelExampleClaim = new fm.liveswitch.ChannelClaim('KickChannel')
kickingChannelExampleClaim.setCanKick(true)
let claims = [kickingChannelExampleClaim]
See also:
To remove a client on the client-side, provide the ClientInfo
to Channel.KickClient
. The following code example shows how to remove a client when you have permissions:
Promise example to remove the client:
client.Register(token).Then(channels => {
// Register the client, returns an array of channels.
var channel = channels[0]; // We registered 1 channel, get that channel from array.
// remoteClientInfo is the ClientInfo object for the user you want to kick.
channel.KickClient(remoteClientInfo).Then(x => {
// Successful.
}).Fail(ex => {
FM.LiveSwitch.Log.Error("Failed to kick user.", ex);
});
});
Async/await example to remove the client:
var channels = await client.Register(token); // Register the client, returns an array of channels.
var channel = channels[0]; // We registered 1 channel, get that channel from array.
try {
// remoteClientInfo is the ClientInfo object for the user you want to kick.
await channel.KickClient(remoteClientInfo);
// Successful
} catch (Exception ex) {
FM.LiveSwitch.Log.Error("Failed to kick user.", ex);
}
See also:
// Register the client, returns an array of channels.
client.register(token).then((IAction1 < Channel[] > ) channels -> {
// We registered 1 channel, get that channel from array.
final Channel channel = channels[0];
channel.kickClient(clientInfo)
.then((IAction1 < Object > ) o -> fm.liveswitch.Log.info("Kicked the client."))
.fail((IAction1 < Exception > ) ex -> fm.liveswitch.Log.error("Failed to kick client.", ex));
}).fail((IAction1 < Exception > ) ex -> fm.liveswitch.Log.error("Failed to register user.", ex));
See also:
Promise example to remove a client:
// Register the client, returns an array of channels.
client?.register(withToken: token).then(resolveActionBlock: {
obj in
let channels = obj as! [FMLiveSwitchChannel]
let channel = channels[0];
// We registered 1 channel, get that channel from array.
// Kick the client using the RemoteClientInfo.
channel.kickClient(withRemoteClientInfo: remoteClientInfo).then(resolveActionBlock: {
client in
// Successful
})
.fail(rejectActionBlock: {
ex in FMLiveSwitchLog.error(withMessage: "Failed to kick client.", ex: ex)
})
})
.fail(rejectActionBlock: {
ex in FMLiveSwitchLog.error(withMessage: "Failed to register client.", ex: ex)
})
See also:
Register the client, returns an array of channels.
let channels = await client.register(token)
let channel = channels[0] // We registered 1 channel, get that channel from array.
Promise example to remove the client:
channel
.kickClient(remoteClientInfo: fm.liveswitch.ClientInfo)
.then((x) => {
// Successful.
})
.fail((ex) => {
fm.liveswitch.Log.error("Failed to kick user.", ex);
});
Async/await example to remove the client:
try {
await channel.kickClient(remoteClientInfo: fm.liveswitch.ClientInfo);
// Successful
} catch (ex) {
fm.liveswitch.Log.error("Failed to kick user.", ex);
}
See also:
To remove a client on the server side, use the REST API.
The following cURL command shows how to remove a client from a channel:
curl --location -g --request DELETE 'https://liveswitch.io:9443/admin/api/v1/applications/{applicationId}/channels/{channelId}/users/{userId}' \
--header 'x-api-key: <your-api-key>' \
--header 'Accept: application/json' \
--header 'odata.metadata: minimal' \
--header 'odata.streaming: true' \
--data-raw ''