Skip to main content
Android
iOS
Web
Windows
Unity
Flutter
React Native

SDK quickstart

Instant messaging enhances user engagement by enabling users to connect and form a community within the app. Increased engagement can lead to increased user satisfaction and loyalty to your app. An instant messaging feature can also provide real-time support to users, allowing them to get help and answers to their questions quickly. The Chat SDK enables you to embed real-time messaging in any app, on any device, anywhere.

This page guides you through implementing peer-to-peer messaging into your app using the Chat SDK for Windows.

Understand the tech

The following figure shows the workflow of sending and receiving peer-to-peer messages using Chat SDK.

understand

  1. Clients retrieve an authentication token from your app server.
  2. Users log in to Chat using the app key, their user ID, and token.
  3. Clients send and receive messages through Chat as follows:
    1. Client A sends a message to Client B. The message is sent to Chat.
    2. The server delivers the message to Client B. When Client B receives a message, the SDK triggers an event.
    3. Client B listens for the event to read and display the message.

Prerequisites

In order to follow the procedure on this page, you must have:

  • A device running Windows 7 or higher.
  • Visual Studio IDE 2019 or later
  • .Net Framework 4.5.2 or later

Project setup

This section shows how to integrate Chat SDK into your project.

  1. Create a Windows project

    1. Open Visual Studio and Create a C# WPF app.
    2. Set the Active solution configuration as Debug and Active solution platform as x64.
  2. Integrate the Chat SDK

    1. Download the Chat SDK NuGet package.

    2. In Solution Explorer, right-click <project-name> and select Manage NuGet Packages....

    3. On the NuGet: <project-name> page, select the Gear icon at the top right.

    4. In Options,

      1. Click + at the top right, then select the new package source.
      2. Set Name, then set Source to the parent directory of the Nuget package resides.
      3. Click OK.
    5. Go back to the NuGet: <project-name> page, open the Package source drop-down list at the top right, then select the package you just added.

    6. In Browse on the NuGet: <project-name> page, select agora_chat_sdk, then click Install.

      If you don't see agora_chat_sdk, refresh the page.

    7. In Preview Changes, click OK

You have installed Chat SDK.

Implement peer-to-peer messaging

This section shows how to use the Chat SDK to implement peer-to-peer messaging in your app, step by step.

Create the UI

In your project, create a simple UI that consists of the following elements:

  • A Button to Join or Leave Agora Chat.
  • A TextBox box to specify the recipient user ID.
  • A TextBox box to enter a text message.
  • A Button to send the text message.
  • A scrollable layout to display sent and received messages.

To add the UI framework to your Windows project, In Solution Explorer, open <project-name> > MainWindow. xaml, then replace the file contents with the following:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:AgoraWindowsChat"
xmlns:ComponentModel="clr-namespace:System.ComponentModel;assembly=WindowsBase" x:Class="AgoraWindowsChat.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="457" Width="804">
<Grid x:Name="mainGrid">
<Button x:Name="btnJoinLeave" Content="Join" HorizontalAlignment="Left" Margin="662,53,0,0" VerticalAlignment="Top" Height="36" Width="107" Click="JoinLeave_Click" Background="#FF4B5ADE" FontSize="18">
<Button.Foreground>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.GradientInactiveCaptionColorKey}}"/>
</Button.Foreground>
</Button>
<TextBox x:Name="eReciepientUserId" HorizontalAlignment="Left" Height="39" Margin="10,50,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="20" Width="642" Foreground="Gray" Opacity="1.0" Text="">
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock FontStyle="Normal" Text="Recipient User Id"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>

<Button x:Name="btnMessageSend" Content="&gt;&gt;" HorizontalAlignment="Left" Margin="662,334,0,0" VerticalAlignment="Top" Height="36" Width="107" Click="MessageSend_Click" Background="#FF4B5ADE" FontSize="18">
<Button.Foreground>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.GradientInactiveCaptionColorKey}}"/>
</Button.Foreground>
</Button>
<TextBox x:Name="eMessage" HorizontalAlignment="Left" Height="39" Margin="5,331,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="652" FontSize="20" Foreground="Gray" Opacity="1.0" Text="" >
<TextBox.Resources>
<VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentX="Left">
<VisualBrush.Visual>
<TextBlock FontStyle="Normal" Text="Message"/>
</VisualBrush.Visual>
</VisualBrush>
</TextBox.Resources>
<TextBox.Style>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="Text" Value="{x:Null}">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
<Trigger Property="Text" Value="">
<Setter Property="Background" Value="{StaticResource HelpBrush}"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Label x:Name="appNameLabel" Content=" agoraChatQuickStart" HorizontalAlignment="Left" Height="45" Margin="10,0,0,0" VerticalAlignment="Top" Width="759" Background="#FF4655D6" FontSize="22" FontWeight="Bold" Foreground="White"/>
<ScrollViewer x:Name="scrollMessagesView" HorizontalAlignment="Left" Height="198" Margin="10,94,0,0" VerticalAlignment="Top" Width="763" Foreground="#FF000000" Background="Linen" RenderTransformOrigin="0.5,0.5" VerticalScrollBarVisibility="Auto">
<StackPanel></StackPanel>
</ScrollViewer>
</Grid>
</Window>
Copy

Handle the system logic

This section shows you how to add Chat SDK headers and setup logging. To do this:

  1. Import the Agora namespaces

    In the Solution Explorer, select <project-name> > MainWindow.xaml, and double-click it to open the MainWindow.xaml.cs file. Add the following lines to the namespaces list in the file:

    using AgoraChat;
    using AgoraChat.MessageBody;
    Copy
  2. Log events and show status updates to your users

    In the MainWindow class, add the following helper method:

    private void showLog(string log)
    {
    // Show a message box
    Dip?.Invoke(() =>
    {
    MessageBox.Show(log);
    });

    // Write log
    Console.WriteLine(log);
    }
    Copy

Send and receive messages

When a user opens the app, you instantiate and initialize a SDKClient. When the user clicks the Join button, the app logs in to Agora Chat. When a user types a message in the text box and then presses Send, the typed message is sent to another registered user. When the app receives a message from Agora Chat, the message is displayed in the message list. This simple workflow enables you to rapidly build a Chat client with basic functionality.

The following figure shows the API call sequence for implementing this workflow.

image

To implement this workflow in your app, take the following steps:

  1. Declare connection variables

    In the MainWindow class, add the following declarations:

    private readonly string userId = "<User ID of the local user>"
    private string token = "<Your authentication token>"
    private readonly string app_key = "<App key from Agora console>"
    private bool isJoined = false;
    // Update the UI from callbacks on a separate thread
    private readonly System.Windows.Threading.Dispatcher? Dip = null;
    Copy
  2. Set up Chat when the app starts

    When the app starts, you create an instance of SDKClient and set up delegates to handle connection and Chat events. To do this, replace the MainWindow() constructor in the MainWindow class with the following:

    public MainWindow()
    {
    // Initialize window component
    InitializeComponent();
    // Initialize the thread dispatcher
    Dip = System.Windows.Threading.Dispatcher.CurrentDispatcher;
    // Initialize Chat SDK client
    setupChatClient();
    // Add connection and chat delegates to handle callbacks
    SDKClient.Instance.AddConnectionDelegate(this);
    SDKClient.Instance.ChatManager.AddChatManagerDelegate(this);
    // Execute the CloseWindow method when the app closes
    Closed += CloseWindow;
    }
    Copy
  3. Initialize the SDKClient

    To implement peer-to-peer messaging, you use Chat SDK to initialize a SDKClient instance. In the MainWindow class, add the following method:

    private void setupChatClient()
    {
    var options = new Options(appKey: app_key);
    options.UsingHttpsOnly = true;
    // Initialize the chat SDKClient
    SDKClient.Instance.InitWithOptions(options);
    }
    Copy
  4. Log in to Agora Chat

    When a user clicks Join, your app logs in to Agora Chat. When they click Leave, the app logs out. To implement this logic, add the following method after showLog() in the MainWindow class:

    private void JoinLeave_Click(object sender, RoutedEventArgs e)
    {
    Button button = (Button)this.FindName("btnJoinLeave");

    if (isJoined)
    {
    SDKClient.Instance.Logout(true, callback: new CallBack(
    onSuccess: () =>
    {
    showLog("Sign out from Agora Chat succeed");
    Dip?.Invoke(() =>
    {
    button.Content = "Join";
    });
    isJoined = false;

    },
    onError: (code, desc) =>
    {
    showLog(desc);
    }
    ));
    }
    else
    {
    // Log in to the Chat service with userId and Agora token.
    SDKClient.Instance.LoginWithAgoraToken(userId, token, callback: new CallBack(
    onSuccess: () =>
    {
    showLog("Sign in to Agora Chat succeed");
    isJoined = false;
    Dip?.Invoke(() =>
    {
    button.Content = "Leave";
    });
    },
    onError: (code, desc) =>
    {
    if (code == 200)
    { // Already joined
    isJoined = true;
    Dip?.Invoke(() =>
    {
    button.Content = "Leave";
    });
    }
    else
    {
    showLog(desc);
    }
    }
    ));
    }
    }
    Copy
  5. Send a message

    When a user types a message and presses the Send button, the app sends the message to the recipient. To do this, add the following method to the MainWindow class, after JoinLeave_Click():

    private void MessageSend_Click(object sender, RoutedEventArgs e)
    {
    if (eReciepientUserId.Text.Equals("") || eMessage.Text.Equals(""))
    {
    showLog("Enter a recipient name and a message");
    return;
    }
    //Send Message
    Message msg = Message.CreateTextSendMessage(eReciepientUserId.Text, eMessage.Text);
    SDKClient.Instance.ChatManager.SendMessage(ref msg, new CallBack(
    onSuccess: () =>
    {
    // The success callback uses the System.Windows.Threading.Dispatcher to update UI elements

    Dip?.Invoke(() =>
    {
    TextBody? txtBody = msg.Body as TextBody;
    if (txtBody != null)
    {
    displayMessage(txtBody.Text, true);
    }
    eMessage.Text = "";
    });

    },
    onError: (code, desc) =>
    {
    showLog(desc);
    }
    ));
    }
    Copy
  6. Set up callbacks for handling Chat events

    To set up callbacks for handling connection and Chat events, you implement the IConnectionDelegate and IChatManagerDelegate interfaces in the MainWindow class. Update the MainWindow class definition as follows:

    public partial class MainWindow : Window, IConnectionDelegate, IChatManagerDelegate
    Copy
  7. Handle connection events

    To implement all IConnectionDelegate callbacks, add the following code to the MainWindow class:

    public void OnConnected()
    {
    showLog("SDK connected successfully.");
    }

    public void OnDisconnected()
    {
    showLog("SDK disconnected.");
    }

    public void OnLoggedOtherDevice()
    {

    }

    public void OnRemovedFromServer()
    {

    }

    public void OnForbidByServer()
    {

    }

    public void OnChangedIMPwd()
    {

    }

    public void OnLoginTooManyDevice()
    {

    }

    public void OnKickedByOtherDevice()
    {

    }

    public void OnAuthFailed()
    {
    showLog("User authentication failed.");
    }

    public void OnTokenExpired()
    {
    showLog("The token has expired.");
    }

    public void OnTokenWillExpire()
    {
    showLog("The token is about to expire. Get a new token from the token server and renew the token.");
    }
    Copy
  8. Handle Chat events

    To read and display received chat messages, you add code to the OnMessagesReceived callback of the IChatManagerDelegate. To implement all IChatManagerDelegate callbacks, add the following code to the MainWindow class:

    public void OnMessagesReceived(List<Message> messages)
    {
    foreach (Message msg in messages)
    {
    Dip?.Invoke(() =>
    {
    TextBody? txtBody = msg.Body as TextBody;
    if (txtBody != null)
    {
    displayMessage(txtBody.Text, false);
    }
    });

    }
    }

    public void OnCmdMessagesReceived(List<Message> messages)
    {

    }

    public void OnMessagesRead(List<Message> messages)
    {

    }

    public void OnMessagesDelivered(List<Message> messages)
    {

    }

    public void OnMessagesRecalled(List<Message> messages)
    {

    }

    public void OnReadAckForGroupMessageUpdated()
    {

    }

    public void OnGroupMessageRead(List<GroupReadAck> list)
    {

    }

    public void OnConversationsUpdate()
    {

    }

    public void OnConversationRead(string from, string to)
    {

    }

    public void MessageReactionDidChange(List<MessageReactionChange> list)
    {

    }
    Copy
  9. Display chat messages

    To display sent and received messages, add the following method to the MainWindow class:

    private void displayMessage(string messageText, bool isSentMessage)
    {
    // Create a new TextBlock
    TextBlock messageTextBlock = new TextBlock();
    messageTextBlock.Text = messageText;
    messageTextBlock.Padding = new Thickness(10);

    // Set formatting
    ScrollViewer? messageList = FindName("scrollMessagesView") as ScrollViewer;
    if (messageList != null)
    {
    if (isSentMessage)
    {
    messageTextBlock.Background = new SolidColorBrush(Color.FromRgb(220, 248, 198));
    messageTextBlock.HorizontalAlignment = HorizontalAlignment.Right;
    messageTextBlock.Margin = new Thickness(100, 25, 15, 5);
    }
    else
    {
    messageTextBlock.Background = Brushes.White;
    messageTextBlock.HorizontalAlignment = HorizontalAlignment.Left;
    messageTextBlock.Margin = new Thickness(15, 25, 100, 5);
    }

    // Add the message TextBlock to the StackPanel inside the ScrollViewer
    StackPanel? messageStackPanel = messageList.Content as StackPanel;
    if (messageStackPanel != null)
    {
    messageStackPanel.Children.Add(messageTextBlock);
    messageList.ScrollToEnd(); // Scroll to the bottom of the messages
    }
    }
    }
    Copy
  10. Clean up when the window is closed

    Add the following method to the MainWindow class:

    private void CloseWindow(object sender, EventArgs e)
    {
    SDKClient.Instance.ChatManager.RemoveChatManagerDelegate(this);
    SDKClient.Instance.DeleteConnectionDelegate(this);
    }
    Copy

Test your implementation

To ensure that you have implemented Peer-to-Peer Messaging in your app:

  1. Create an app instance for the first user:

    1. Register a user in Agora Console and Generate a user token.

    2. In the MainWindow class, update userId, token, and appKey with values from Agora Console. To get your app key, see Get Chat project information.

    3. Click the Start button. You see the following interface:

      image

  2. Create an app instance for the second user:

    1. Register a second user in Agora Console and generate a user token.

    2. Build a second instance of your app after updating userId and token with values for the second user. Make sure you use the same appKey as for the first user.

    3. Click the Start button to launch the second instance.

  3. On each instance, click Join to log in to Agora Chat.

  4. Edit the recipient name in each app instance to show the user ID of the user logged in to the other instance.

  5. Type a message in the Message box of either instance and press >>. The message is sent and appears on the other app.

    image

  6. Press Leave to log out from Agora Chat.

Reference

This section contains content that completes the information in this page, or points you to documentation that explains other aspects to this product.

  • Avoid blocked callbacks
    Each callback of a Chat client instance is triggered from internal threads. To avoid blocking internal threads, Agora recommends that you execute your operations in other threads when callbacks are triggered.

API reference​

Next steps

In a production environment, best practice is to deploy your own token server. Users retrieve a token from the token server to log in to Chat. To see how to implement a server that generates and serves tokens on request, see Secure authentication with tokens.

vundefined