<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Denize Chan</title>
    <description>The latest articles on DEV Community by Denize Chan (@denize_chan).</description>
    <link>https://dev.to/denize_chan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F874589%2F8a25a6bf-3f8d-43c9-9ccc-279b3587f2e2.png</url>
      <title>DEV Community: Denize Chan</title>
      <link>https://dev.to/denize_chan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/denize_chan"/>
    <language>en</language>
    <item>
      <title>TRTCCalling, a powerful new-gen real-time communication tool</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Fri, 09 Sep 2022 03:24:00 +0000</pubDate>
      <link>https://dev.to/tencentcloud/trtccalling-a-powerful-new-gen-real-time-communication-tool-4k7a</link>
      <guid>https://dev.to/tencentcloud/trtccalling-a-powerful-new-gen-real-time-communication-tool-4k7a</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is TRTCCalling?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;TRTCCalling is a real-time communication solution based on Tencent Real-Time Communication (TRTC) and Tencent Cloud Instant Messaging. It supports one-to-one and group audio/video calls and allows quick integration.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--afUdxodv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lk4p98kwer440e0basjl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--afUdxodv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lk4p98kwer440e0basjl.png" alt="Image description" width="695" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can TRTCCalling do?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Online customer service, online interview, corporate online communication, online consultation, audio/video social networking, and more.&lt;/p&gt;

&lt;p&gt;| Demo address |&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--r017XhO5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg597vvpq3zn9xhyb0kb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--r017XhO5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tg597vvpq3zn9xhyb0kb.png" alt="Image description" width="400" height="400"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://web.sdk.qcloud.com/component/trtccalling/demo/web/latest/index.html#/login"&gt;https://web.sdk.qcloud.com/component/trtccalling/demo/web/latest/index.html#/login&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do I connect to it?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Import the &lt;code&gt;TRTCCalling&lt;/code&gt; component&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--83Oyg1rj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9hftyie53hvm6x2ntaq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--83Oyg1rj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f9hftyie53hvm6x2ntaq.png" alt="Image description" width="602" height="76"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2. Create a &lt;code&gt;TRTCCalling&lt;/code&gt; object&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xMr4MpcX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grztdg6doqr3gnfx7fna.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xMr4MpcX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/grztdg6doqr3gnfx7fna.png" alt="Image description" width="602" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3. Log in&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iabMa9sQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x692q3ybdovze6z6mql7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iabMa9sQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x692q3ybdovze6z6mql7.png" alt="Image description" width="602" height="77"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4. Make a one-to-one call&lt;/strong&gt;&lt;br&gt;
Caller: Make a call&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--To_DCjik--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdys1ip33wfqncqoqidl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--To_DCjik--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdys1ip33wfqncqoqidl.png" alt="Image description" width="602" height="82"&gt;&lt;/a&gt;&lt;br&gt;
Callee: Answer a call&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--h_uq28X8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64cdx4jqf9k8ap26wf98.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--h_uq28X8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/64cdx4jqf9k8ap26wf98.png" alt="Image description" width="602" height="45"&gt;&lt;/a&gt;&lt;br&gt;
Hang up&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--V1xyd9c0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0dlw9c4kwflchgdc393v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--V1xyd9c0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0dlw9c4kwflchgdc393v.png" alt="Image description" width="602" height="29"&gt;&lt;/a&gt;&lt;br&gt;
We invite you to connect TRTCCalling to your product, and we welcome your feedback and suggestions.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Coroutine-Native SRT</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Tue, 06 Sep 2022 04:27:06 +0000</pubDate>
      <link>https://dev.to/tencentcloud/coroutine-native-srt-1p1h</link>
      <guid>https://dev.to/tencentcloud/coroutine-native-srt-1p1h</guid>
      <description>&lt;p&gt;Coroutines are core technologies for modern servers that significantly simplify the logic and facilitate maintenance. SRT is a new streaming protocol that is gradually taking over from RTMP. With its own I/O framework, SRT can mature only by becoming coroutine-native, the first and crucial step of SRS 5.0.&lt;/p&gt;

&lt;p&gt;Since the beginning of 2022, we have explored, discussed, and finally determined the media gateway as the fundamental direction of SRS 5.0, as detailed in Definitions and Solutions of Core Issues with SRS 5.0.&lt;/p&gt;

&lt;p&gt;Though popular with live streaming/broadcasting push, SRT is not supported by web browsers. And that's where the media gateway comes into play. Specifically, it converts SRT into RTMP/HLS/WebRTC to deliver an ultra low-latency broadcasting solution that keeps SRT's powerful cross-border transfer capabilities.&lt;/p&gt;

&lt;p&gt;The foundation lies in coroutine-native SRT, today's topic. It will have a far-reaching impact on SRS 5.0. For more information on its code, see PR#3010.&lt;/p&gt;

&lt;p&gt;First of all, let's talk about its background.&lt;/p&gt;

&lt;p&gt;Introduction&lt;br&gt;
RTMP is widely used in the live push field. It is also one of the most compatible protocols with different live streaming origin servers. &lt;br&gt;
With an increasing number of scenarios and the progress of live streaming, some of the acute problems have emerged:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;TCP push performs poorly in terms of packet loss, RTT, and jitter for long-distance transfer.&lt;/li&gt;
&lt;li&gt;RTMP doesn't support multiple audio tracks or new coding standards such as H.265 and AV1.&lt;/li&gt;
&lt;li&gt;Adobe has abandoned RTMP, which has not been updated for years nor will it be updated in the future.
To solve these problems, the broadcasting field has widely adopted SRT push since 2018, and more and more push devices and platforms have followed suit.
At the end of 2019, SRT push became supported by SRS 4.0. However, there were several shortcomings:&lt;/li&gt;
&lt;li&gt;SRT is implemented in SRS with multiple threads in an asynchronous manner, making it hard to troubleshoot program crashes due to exceptions.&lt;/li&gt;
&lt;li&gt;SRT is implemented in SRS asynchronously, leading to complex code and maintenance.&lt;/li&gt;
&lt;li&gt;SRT playback won't take effect after the HTTP callback, which is triggered by RTMP after the SRT push dependency turns to RTMP. There is no callback for playback.&lt;/li&gt;
&lt;li&gt;SRT needs to be converted into RTMP first before it can be converted into WebRTC, causing a high latency.
The core cause of these problems is that SRT uses independent and asynchronous I/O and multiple threads that cannot be combined with the existing ST coroutines of SRS.
Therefore, SRT must become coroutine-native and fall into the same ST coroutine framework as SRS. This has been achieved in SRS 5.0. For more information on its code, see PR#3010. This is an extremely important feature.
Before moving to the coroutine-native SRT, let's take a look at coroutine native itself, as exemplified by the coroutine-native TCP of ST.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Coroutine-native TCP&lt;br&gt;
To begin with, let's see the following logic of the non-coroutine-native code, that is, async code driven by epoll:&lt;br&gt;
int fd = accept(listen_fd); // Got a TCP connection.&lt;/p&gt;

&lt;p&gt;int n = read(fd, buf, sizeof(buf));&lt;br&gt;
if (n == -1) {&lt;br&gt;
 if (errno == EAGAIN) { // Not ready&lt;br&gt;
 return epoll_ctl(fd, EPOLLIN); // Wait for fd to be ready.&lt;br&gt;
 }&lt;br&gt;
 return n; // Error.&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;printf("Got %d size of data %p", n, buf);&lt;br&gt;
Note: The above is just a sample that helps better express the key logic. You can see epoll sample code for more details.&lt;br&gt;
Generally speaking, read is a business logic, and the data that is read is business data. However, the underlying framework of epoll needs to be called here for fd processing during EAGAIN. As a result, the underlying logic and business logic are mixed, complicating maintenance.&lt;br&gt;
Note: Although NGINX has a packaged framework layer, async callback still exists. If the current function needs to be returned before the fd is ready, many statuses need to be stored and recovered. When the logic is complex, the state machine becomes complicated.&lt;br&gt;
See the following code to see what a coroutine-native logic will be like in this case:&lt;br&gt;
st_netfd_t fd = st_accept(listen_fd); // Got a TCP connection&lt;/p&gt;

&lt;p&gt;int n = st_read(fd, buf, sizeof(buf));&lt;br&gt;
if (n == -1) {&lt;br&gt;
    return n; // Error.&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;printf("Got %d size of data %p", n, buf);&lt;br&gt;
Obviously, there seems to be no EAGAIN. It may be that data is read or an error occurs. No matter what the case is, fd will always be ready. This means no need to store the status and no repeated read attempts, creating a very good experience when using the business logic.&lt;br&gt;
Why is there no EAGAIN for st_read when epoll is still used? Well, there is, but it has been handled less obviously with the coroutine. Let's see the st_readv function:&lt;/p&gt;

&lt;p&gt;ssize_t st_read(_st_netfd_t *fd, void *buf, size_t nbyte) {&lt;br&gt;
    while ((n = read(fd-&amp;gt;osfd, buf, nbyte)) &amp;lt; 0) {&lt;br&gt;
        if (errno == EINTR)&lt;br&gt;
            continue;&lt;br&gt;
        if (!_IO_NOT_READY_ERROR) // Error, if not EAGAIN.&lt;br&gt;
            return -1;&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    /* Wait until the socket becomes readable */
    if (st_netfd_poll(fd, POLLIN) &amp;lt; 0) // EAGAIN
        return -1;
}

return n;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;/p&gt;

&lt;p&gt;During EAGAIN, st_netfd_poll is called, which switches the current coroutine and schedules the thread to execute the next coroutine. In addition, the current coroutine will be recovered at some point when the I/O event arrives or a timeout occurs.&lt;br&gt;
Note: Both the coroutine switch and recovery are implemented in the function and imperceptible to the code called at the upper layer. Therefore, there is no EAGAIN error message or return to the upper-layer function, and no need to store and resume the status.&lt;br&gt;
In summary, do the following to make any protocol coroutine-native:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Call the API once, which will directly return upon success.&lt;/li&gt;
&lt;li&gt;In the case of a failure, check for the error and return if the error is irrelevant to I/O wait.&lt;/li&gt;
&lt;li&gt;Switch the current coroutine and run other coroutines until the arrival of a timeout or the fd event. In the former case, return an error; in the latter case, repeat the above steps.
With that, we can make SRT coroutine-native.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Coroutine-native SRT&lt;br&gt;
The srt_recvmsg function is used as an example. It resembles the read function of TCP and is as defined below:&lt;/p&gt;

&lt;p&gt;SRT_API int srt_recvmsg (SRTSOCKET u, char* buf, int len);&lt;/p&gt;

&lt;p&gt;Implement SrsSrtSocket::recvmsg , another function similar to st_read : &lt;/p&gt;

&lt;p&gt;srs_error_t SrsSrtSocket::recvmsg(void* buf, size_t size, ssize_t* nread) {&lt;br&gt;
 while (true) {&lt;br&gt;
 int ret = srt_recvmsg(srt_fd_, (char*)buf, size);&lt;br&gt;
 if (ret &amp;gt;= 0) { // Receive message ok.&lt;br&gt;
      recv_bytes_ += ret; &lt;br&gt;
 *nread = ret;&lt;br&gt;
 return err;&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;// Got something error, return immediately.&lt;br&gt;
 if (srt_getlasterror(NULL) != SRT_EASYNCRCV) {&lt;br&gt;
 return srs_error_new(ERROR_SRT_IO, "srt_recvmsg");&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;// Wait for the fd ready or error, switch to other coroutines.&lt;br&gt;
 if ((err = wait_readable()) != srs_success) { // EAGAIN.&lt;br&gt;
 return srs_error_wrap(err, "wait readable");&lt;br&gt;
 }&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;return err;&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;As we can see, wait_readable implements coroutine switch and recovery just like st_read , but with the st_cond_t condition variable: &lt;/p&gt;

&lt;p&gt;srs_error_t SrsSrtSocket::wait_readable() {&lt;br&gt;
  srt_poller_-&amp;gt;mod_socket(this, SRT_EPOLL_IN);&lt;br&gt;
  srs_cond_timedwait(read_cond_);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Note: The SRT_EPOLL_IN event listened by epoll is modified before the fd becomes readable and the condition variable is triggered. &lt;br&gt;
SrsSrtPoller::wait is the function that triggers the condition variable. Its implementation is as follows:&lt;/p&gt;

&lt;p&gt;srs_error_t SrsSrtPoller::wait(int timeout_ms, int* pn_fds) {&lt;br&gt;
 int ret = srt_epoll_uwait(srt_epoller_fd_, events_.data(), events_.size());&lt;br&gt;
 for (int i = 0; i &amp;lt; ret; ++i) {&lt;br&gt;
 if (event.events &amp;amp; SRT_EPOLL_IN) {&lt;br&gt;
      srt_skt-&amp;gt;notify_readable();&lt;br&gt;
 }&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;void SrsSrtSocket::notify_readable() {&lt;br&gt;
 srs_cond_signal(read_cond_);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Now the SRT API becomes coroutine-native. The operation is similar for other APIs such as srt_sendmsg, srt_connnect, and srt_accept.&lt;br&gt;
Let's compare coroutine native and the original callback.&lt;/p&gt;

&lt;p&gt;Coroutine native vs callback&lt;br&gt;
After making the SRT coroutine-native, we succeeded in separating the business logic from the underlying code, thereby clarifying the upper-layer code logic.&lt;br&gt;
Let's see the accept logic, where event processing is triggered by epoll to create the srt_conn data structure: &lt;/p&gt;

&lt;p&gt;while (run_flag) {&lt;br&gt;
 int ret = srt_epoll_wait(_pollid, read_fds, &amp;amp;rfd_num, write_fds);&lt;br&gt;
 for (int index = 0; index &amp;lt; rfd_num; index++) {&lt;br&gt;
    SRT_SOCKSTATUS status = srt_getsockstate(read_fds[index]);&lt;br&gt;
 srt_handle_connection(status, read_fds[index], "read fd");&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;void srt_server::srt_handle_connection(SRT_SOCKSTATUS status, SRTSOCKET input_fd) {&lt;br&gt;
 if (status == SRTS_LISTENING) {&lt;br&gt;
    conn_fd = srt_accept(input_fd, (sockaddr*)&amp;amp;scl, &amp;amp;sclen);&lt;br&gt;
    _handle_ptr-&amp;gt;add_newconn(conn_fd, SRT_EPOLL_IN);&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;void srt_handle::add_newconn(SRT_CONN_PTR conn_ptr, int events) {&lt;br&gt;
    _push_conn_map.insert(std::make_pair(conn_ptr-&amp;gt;get_path(), conn_ptr));&lt;br&gt;
    _conn_map.insert(std::make_pair(conn_ptr-&amp;gt;get_conn(), conn_ptr));&lt;br&gt;
 int ret = srt_epoll_add_usock(_handle_pollid, conn_ptr-&amp;gt;get_conn(), &amp;amp;events);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Note: The created srt_conn is stored in the global data structure and continuously modified in the follow-up callback events.&lt;br&gt;
The following is a coroutine-native business logic, which starts the processing coroutine after receiving the session:&lt;/p&gt;

&lt;p&gt;srs_error_t SrsSrtListener::cycle() {&lt;br&gt;
 while (true) {&lt;br&gt;
 srs_srt_t client_srt_fd = srs_srt_socket_invalid();&lt;br&gt;
    srt_skt_-&amp;gt;accept(&amp;amp;client_srt_fd);&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;srt_server_-&amp;gt;accept_srt_client(srt_fd);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;srs_error_t SrsSrtServer::accept_srt_client(srs_srt_t srt_fd) {&lt;br&gt;
 fd_to_resource(srt_fd, &amp;amp;srt_conn);&lt;br&gt;
  conn_manager_-&amp;gt;add(srt_conn);&lt;br&gt;
  srt_conn-&amp;gt;start();&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;​Note: Although srt_conn is maintained by global variables, it is the coroutine-native execution logic—not callback logic or epoll processing—that is relevant. &lt;br&gt;
In the callback logic, you need to view the epoll callback event before maintaining or understanding the code. What's worse, the srt_conn status is modified by different events, making it hard to understand the lifecycle of the object; while in the coroutine-native logic, its lifecycle is contained in the coroutine, it is processed in a coroutine after srt_conn is received, and further read and write operations are also performed in the coroutine.&lt;br&gt;
Let's move on to the read processing logic of srt_conn , where the native read function of SRT is used and the callback is triggered by the epoll event:&lt;br&gt;
while (run_flag) {&lt;br&gt;
 int ret = srt_epoll_wait(_pollid, read_fds, &amp;amp;rfd_num, write_fds);&lt;br&gt;
 for (int index = 0; index &amp;lt; rfd_num; index++) {&lt;br&gt;
    SRT_SOCKSTATUS status = srt_getsockstate(read_fds[index]);&lt;br&gt;
 srt_handle_data(status, read_fds[index], "read fd");&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;void srt_handle::handle_srt_socket(SRT_SOCKSTATUS status, SRTSOCKET conn_fd) {&lt;br&gt;
 auto conn_ptr = get_srt_conn(conn_fd);&lt;br&gt;
 int mode = conn_ptr-&amp;gt;get_mode();&lt;br&gt;
 if (mode == PUSH_SRT_MODE &amp;amp;&amp;amp; status == SRTS_CONNECTED) {&lt;br&gt;
 handle_push_data(status, path, subpath, conn_fd);&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;void srt_handle::handle_push_data(SRT_SOCKSTATUS status, SRTSOCKET conn_fd) {&lt;br&gt;
  srt_conn_ptr = get_srt_conn(conn_fd);&lt;br&gt;
 if (status != SRTS_CONNECTED) { // Error.&lt;br&gt;
 close_push_conn(conn_fd);&lt;br&gt;
 return;&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;ret = srt_conn_ptr-&amp;gt;read_async(data, DEF_DATA_SIZE);&lt;br&gt;
 if (ret &amp;lt;= 0) { // Error.&lt;br&gt;
 if (srt_getlasterror(NULL) != SRT_EASYNCRCV) {&lt;br&gt;
 return;&lt;br&gt;
 }&lt;br&gt;
 close_push_conn(conn_fd);&lt;br&gt;
 return;&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;srt2rtmp::get_instance()-&amp;gt;insert_data_message(data, ret, subpath);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Note: We need to process a variety of statuses in the callback, but the srt_conn status changes are determined by different callbacks, so it is not easy to determine the main processing logic of the session.&lt;/p&gt;

&lt;p&gt;A coroutine-native version of the SRT business logic will be like:&lt;/p&gt;

&lt;p&gt;srs_error_t SrsMpegtsSrtConn::do_publishing() {&lt;br&gt;
 while (true) {&lt;br&gt;
 ssize_t nb = 0;&lt;br&gt;
 if ((err = srt_conn_-&amp;gt;read(buf, sizeof(buf), &amp;amp;nb)) != srs_success) {&lt;br&gt;
 return srs_error_wrap(err, "srt: recvmsg");&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;if ((err = on_srt_packet(buf, nb)) != srs_success) {&lt;br&gt;
 return srs_error_wrap(err, "srt: process packet");&lt;br&gt;
 }&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Note: The lifecycle of srt_conn is clear, and its status is returned in the error within the cycle, which can be regarded as the main loop for this session. It will not enter the epoll loop of SRT due to read, and you can ignore the async event trigger and processing during maintenance. &lt;/p&gt;

&lt;p&gt;Again, different information is required for code maintenance in different logics. In the async callback logic, you need to know the statuses of the current object, the modified statuses, and the impact of other async events from the callback function. While in the coroutine-native logic, these statuses are irrelevant, and the creation and execution of the coroutine are linear. Or we can say that these statuses are in the coroutine function callback.&lt;/p&gt;

&lt;p&gt;Note: The async callback status cannot be in the function callback, as the async callback stack cannot store the srt_conn status. In essence, it is a coroutine which stores the status of the epoll loop. While a coroutine is created according to each srt_conn, and the corresponding srt_conn status is stored in its stack. &lt;/p&gt;

&lt;p&gt;In fact, the async callback status can only be stored in the global data structure, while the coroutine status can be stored in each local variable. The local variable of each function is unique to the coroutine and can be used as long as the coroutine doesn't end.&lt;/p&gt;

&lt;p&gt;What is next&lt;/p&gt;

&lt;p&gt;The coroutine-native SRT still faces some problems and requires follow-up actions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Directly convert SRT into WebRTC to lower the latency in live streaming.&lt;/li&gt;
&lt;li&gt;Replace TCP with SRT for long-linkage transfer between some servers, such as cross-border RTMP forwarding.&lt;/li&gt;
&lt;li&gt;Improve the SRT tool chain, such as srs-bench, to support stress testing of SRT streams.
Join the SRS open-source community to make a powerful streaming media server available for all.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;One more thing&lt;br&gt;
In case you may wonder, let me tell you the differences between a commercial video cloud SRT server and an open-source SRT server as well as the optimizations.&lt;br&gt;
Note: Some optimizations are not suitable for open-source projects, as open-source servers put more emphasis on protocol standardization and compatibility. Therefore, a commercial cloud computing server can be totally different from an open-source server. Even the Linux kernel of the commercial server will greatly differ from that of the open-source server.&lt;/p&gt;

&lt;p&gt;Here, some of SRT's most troublesome problems are the high retransmission rate and poorer performance than TCP/QUIC when the bandwidth is limited. Tencent Cloud makes the following optimizations accordingly:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SRT retransmission disorder adaptation: When disordered packets are received, the system will wait for N packets before initiating the first retransmission according to the current degree of the disorder. The native SRT disorder has a fixed value, which can be adjusted to be more adaptive to the network disorder conditions.&lt;/li&gt;
&lt;li&gt;SRT transfer parameter optimization: The retransmission rate is halved after the parameter optimization.&lt;/li&gt;
&lt;li&gt;Addition of the BBR congestion control algorithm: The native SRT congestion control is weak, and the evaluated bandwidth fluctuates greatly, both of which are resolved by adding the BBR congestion control algorithm.&lt;/li&gt;
&lt;li&gt;SRT multi-linkage transfer improved with bandwidth aggregation: The auto mode for live streaming is added to SRT, in addition to its native backup and broadcast modes. In this way, the bandwidths of multiple ENIs are aggregated for live streaming, with smart and dynamic linkage selection.&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Tencent Cloud GPU Service</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Fri, 26 Aug 2022 08:04:02 +0000</pubDate>
      <link>https://dev.to/tencentcloud/tencent-cloud-gpu-service-1hng</link>
      <guid>https://dev.to/tencentcloud/tencent-cloud-gpu-service-1hng</guid>
      <description>&lt;p&gt;Not sure which Tencent Cloud GPU instance is right for you? Still fumbling a way to elegantly install the driver and other underlying development tools? These are common questions that bother deep learning researchers and developers. No worries. This document shares all you need to know through the best practices of Tencent Cloud GPU instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment and objective&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The mainstream Tencent Cloud GPU Computing GN7 model with an NVIDIA Tesla T4 GPU is selected as an example, to be more specific, GN7.5XLARGE80. This model features a high comprehensive performance offered by 20 CPU cores and 80 GB memory, making it suitable for general deep neural network training. In addition, it is the most cost-effective GPU T4 model in the world.&lt;/p&gt;

&lt;p&gt;Purchase here. Pay-as-you-go models are even more flexible for experiments.&lt;/p&gt;

&lt;p&gt;Instance in this tutorial: GPU models like GN7 (recommended) or GN10X&lt;/p&gt;

&lt;p&gt;Recommended system image: Ubuntu 18.04 (note that you don't need to select &lt;strong&gt;Automatically install GPU driver on the backend&lt;/strong&gt;.)&lt;/p&gt;

&lt;p&gt;Other information: Beijing Zone 5, 1 Mbps public network bandwidth, and 100 GB system disk, which can be selected as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing CUDA Driver/Toolkit&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AZgqmivs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akeodx86qbqfrf5yby3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AZgqmivs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akeodx86qbqfrf5yby3m.png" alt="Image description" width="865" height="302"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install the DEB package from the official website&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1i5_sEFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hk7trc2o5icpjp8rb6u8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1i5_sEFO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hk7trc2o5icpjp8rb6u8.png" alt="Image description" width="865" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Download CUDA Toolkit 10.2 from NVIDIA's official website.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.nvidia.com/cuda-downloads"&gt;https://developer.nvidia.com/cuda-downloads&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the download method based on your environment. Here, DEB package installation is selected as shown below:&lt;/p&gt;

&lt;p&gt;Run the following command as prompted:&lt;/p&gt;

&lt;p&gt;wget &lt;a href="https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin"&gt;https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin&lt;/a&gt; sudo mv cuda-ubuntu1804.pin /etc/apt/preferences.d/cuda-repository-pin-600 sudo apt-key adv --fetch-keys &lt;a href="https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub"&gt;https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/7fa2af80.pub&lt;/a&gt; sudo add-apt-repository "deb &lt;a href="http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/"&gt;http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/&lt;/a&gt; /" sudo apt-get update sudo apt-get -y install cuda&lt;/p&gt;

&lt;p&gt;You can see that the official APT repository source of NVIDIA is installed in the system and &lt;code&gt;apt install cuda&lt;/code&gt; is executed. Note that the last step of installation takes about five minutes and may be interrupted due to network and other issues, which can be fixed after a retry or two.&lt;/p&gt;

&lt;p&gt;Note: The server needs to be restarted here.&lt;/p&gt;

&lt;p&gt;Then how to know what is installed and verify the installation?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify GPU driver installation - view the device information&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The NVIDIA GPU driver is a kernel module supporting CUDA programming. In the above steps, the driver is installed in the form of Dynamic Kernel Module Support (DKMS). This type of kernel module is not in the kernel source tree, but it can be automatically recompiled every time the kernel is updated and upgraded to generate a new initramfs. In addition, it is dynamically loaded as the system starts. In short, the driver only needs to be installed once, which is very convenient.&lt;/p&gt;

&lt;p&gt;Log in after the restart and verify whether the driver module has been dynamically loaded.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zR7d_A2R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fg8td4z65vy9vxcw64dm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zR7d_A2R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fg8td4z65vy9vxcw64dm.png" alt="Image description" width="865" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As can be seen, the NVIDIA instead of Nouveau driver is loaded.&lt;/p&gt;

&lt;p&gt;Read more at: &lt;a href="https://www.tencentcloud.com/dynamic/insights/sample-article/100331"&gt;https://www.tencentcloud.com/dynamic/insights/sample-article/100331&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gpu</category>
      <category>cvm</category>
      <category>webdev</category>
      <category>cloud</category>
    </item>
    <item>
      <title>How to Design a Proper Marketing Email Template with Tencent Cloud’s Simple Email Service</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Tue, 23 Aug 2022 03:58:05 +0000</pubDate>
      <link>https://dev.to/tencentcloud/how-to-design-a-proper-marketing-email-template-with-tencent-clouds-simple-email-service-11lm</link>
      <guid>https://dev.to/tencentcloud/how-to-design-a-proper-marketing-email-template-with-tencent-clouds-simple-email-service-11lm</guid>
      <description>&lt;p&gt;The content is of great importance to a marketing email, as it directly affects the deliverability, click rate, and conversion rate. The following are some of our tips for writing a marketing email:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create an eye-catching subject line&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Of the over six billion email accounts in the world, 80% of them only read the subject line, and the rest 20% read the body. That's why the subject line matters.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A subject line should be created in friendly language. Do not make the recipients feel that they are forced or persuaded to buy something, in which case they may report the email as spam.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Include the primary keyword in the first three words and the secondary keyword in the last three words in the subject line. This works well for customer acquisition with a long, seemingly endless list.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A proper subject should be neither too long nor too short. You'd better limit it to ten words and put the most important words at the beginning.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create a witty subject that includes hot news or internet buzzwords in a tailored and pleasing manner.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;2. Create valuable email content&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The quality of an email determines whether the recipients are willing to know about or even buy the product.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Pay attention to readability, as email marketing is also content marketing, so users' reading habits should be taken into full consideration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You should test and adjust the email template format. Simple Email Service | Tencent Cloud allows you to preview and adjust the format when creating a template.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can create images or text with hyperlinks, which are light-loaded and easy to open, making user interaction easier.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use HTML emails instead of embedding text inside an image, as it often happens that an image cannot be displayed due to ISP filtering, poor network condition or other issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Images should be proportionate to text.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can tailor emails for different types of customers to quickly understand their preferences and win them over.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Promote your products and services at a festival or under a special theme to guide purchase decisions. Simple Email Service | Tencent Cloud enables you to reach customers from over 200 countries and regions.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Craft a marketing email with branding elements. After all, an email is used to build your brand and achieve a high conversion rate.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Find out more at: &lt;a href="https://www.tencentcloud.com/dynamic/insights/sample-article/100329"&gt;https://www.tencentcloud.com/dynamic/insights/sample-article/100329&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Integrate In-App Chat Module to Your Flutter APP with Tencent Cloud IM in 6 Steps</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Wed, 17 Aug 2022 08:19:50 +0000</pubDate>
      <link>https://dev.to/tencentcloud/integrate-in-app-chat-module-to-your-flutter-app-with-tencent-cloud-im-in-6-steps-32l9</link>
      <guid>https://dev.to/tencentcloud/integrate-in-app-chat-module-to-your-flutter-app-with-tencent-cloud-im-in-6-steps-32l9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Abstract&lt;/strong&gt;&lt;br&gt;
By the end of this tutorial, you will be able to use Tencent Cloud IM TUIKit to integrate the Chat module to Flutter APP. Tencent Cloud IM Chat is more capable than this, check more information here!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Tencent Cloud IM In-App Chat for Flutter？&lt;/strong&gt;&lt;br&gt;
Tencent Cloud IM provides Chat API for apps on Flutter. It integrates diverse chat capabilities such as one-to-one chat, group chat, chat room, and system notification into its SDKs.&lt;br&gt;
Moreover, its TUIkit library contains complex UI components and relative business logic, helps you integrate In-App chat to your Flutter App easily and quickly.&lt;br&gt;
Choosing Tencent Cloud IM can bring you and your customers closer together.&lt;/p&gt;

&lt;p&gt;The Solutions of Integrating Tencent Cloud IM Chat for Flutter&lt;br&gt;
There are three solutions to integrate Tencent Cloud IM Chat to your Flutter apps, including modifying the DEMO, using TUIKit, and invoke the SDK API directly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution &amp;amp; Scenario&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Chat DEMO: IM DEMO is a complete chat app. The code isopen source. If you need to implement a similar scene, you can do secondary development based on it. Here is the DEMO.&lt;/p&gt;

&lt;p&gt;TUIKit library with UI components and business logic: TUIKit library provides universal UI components, such as conversation list, chat , and contact list, etc. You can quickly build the In-App chat module with your actual business needs based on it. It is recommended to use as priority.&lt;/p&gt;

&lt;p&gt;Invoke SDK API and self-implementing UI: If the UI of TUIKit cannot meet your business needs, or you need more customization, this solution could be your option.&lt;/p&gt;

&lt;p&gt;This tutorial will introduce how to implement the In-App Chat module with the second solution, TUIKit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Environment Requirements&lt;/strong&gt;&lt;br&gt;
Platform &amp;amp; Version&lt;br&gt;
Flutter: Flutter 2.8.1 or later.&lt;br&gt;
Android: Android Studio 3.5 or later; API 21 (Android 5.0) or late for apps.&lt;br&gt;
iOS: Xcode 11.0 or later. Ensure that your project has a valid developer signature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You have signed up for a Tencent Cloud account and completed identity verification.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Created a Chat application, and get the &lt;code&gt;SDKAppID&lt;/code&gt;. Ref: Creating and Upgrading an Application | Tencent Cloud&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Start Integration&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Create two accounts for testing&lt;/strong&gt;&lt;br&gt;
Log in to the IM console.&lt;br&gt;
Select Auxiliary Tools &amp;gt; UserSig Generation and Verification on the left sidebar. Generate two pairs of "UserID" and the corresponding "UserSig", and copy the "key" information.&lt;br&gt;
Tips: You may create "user1" and "user2" here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pk8qZB---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54kcavq848ehd9anknd7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3Pk8qZB---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/54kcavq848ehd9anknd7.png" alt="Image description" width="880" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Load TUIKit library for Flutter&lt;/strong&gt;&lt;br&gt;
It's unnecessary to install the IM SDK manually, as TUIKit also convers it.&lt;br&gt;
Please execute this command in Terminal on your Flutter project.&lt;/p&gt;

&lt;p&gt;flutter pub add tim_ui_kit &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Initialize and log in&lt;/strong&gt;&lt;br&gt;
Initialize&lt;br&gt;
Initialize the TUIKit after you app starts.&lt;br&gt;
Get the instance of TUIKit first by "TIMUIKitCore.getInstance()", followed by initializing it, "init()", with your "sdkAppID".&lt;/p&gt;

&lt;p&gt;/// main.dart&lt;br&gt;
import 'package:tim_ui_kit/tim_ui_kit.dart';&lt;/p&gt;

&lt;p&gt;final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();&lt;br&gt;
 @override&lt;br&gt;
 void initState() {&lt;br&gt;
    _coreInstance.init(&lt;br&gt;
      sdkAppID: 0, // Replace 0 with the SDKAppID of your IM application&lt;br&gt;
      loglevel: LogLevelEnum.V2TIM_LOG_DEBUG,&lt;br&gt;
      listener: V2TimSDKListener()); &lt;br&gt;
 super.initState();&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Log in testing account&lt;/p&gt;

&lt;p&gt;Now, you can log in one of the testing accounts, generated on Step 1, to start the IM module.&lt;br&gt;
Log in by "_coreInstance.login" .&lt;/p&gt;

&lt;p&gt;import 'package:tim_ui_kit/tim_ui_kit.dart';&lt;/p&gt;

&lt;p&gt;final CoreServicesImpl _coreInstance = TIMUIKitCore.getInstance();&lt;br&gt;
_coreInstance.login(userID: userID, userSig: userSig);&lt;/p&gt;

&lt;p&gt;Caveat: Importing UserSig to your application is ONLY for Debugging purposes and cannot be applied for the Release version. Before publishing your app, you should generate your UserSig from your server. Refers to: Generating UserSig | Tencent Cloud&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Implementing conversation list page&lt;/strong&gt;&lt;br&gt;
You can take the conversation (channel) list page as the homepage of your Chat module, covering the conversation with all users and groups that have chat records.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DxjFk99e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rh44tngnfz3dgsujmitb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DxjFk99e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rh44tngnfz3dgsujmitb.png" alt="Image description" width="828" height="1792"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You can create a "Conversation" class, with "TIMUIKitConversation" on its "body", to render the conversation list.&lt;br&gt;
The only parameter you need to provide at least is "onTapItem" callback, aimed at navigating to the Chat page for each conversation. The "Chat" class will be introduced in the next step.&lt;/p&gt;

&lt;p&gt;import 'package:flutter/material.dart';&lt;br&gt;
import 'package:tim_ui_kit/tim_ui_kit.dart';&lt;/p&gt;

&lt;p&gt;class Conversation extends StatelessWidget {&lt;br&gt;
const Conversation({Key? key}) : super(key: key);&lt;br&gt;
@override&lt;br&gt;
Widget build(BuildContext context) {&lt;br&gt;
return Scaffold(&lt;br&gt;
  appBar: AppBar(&lt;br&gt;
    title: const Text(&lt;br&gt;
 "Message",&lt;br&gt;
      style: TextStyle(color: Colors.black),&lt;br&gt;
 ),&lt;br&gt;
 ),&lt;br&gt;
  body: TIMUIKitConversation(&lt;br&gt;
    onTapItem: (selectedConv) {&lt;br&gt;
 Navigator.push(&lt;br&gt;
          context,&lt;br&gt;
 MaterialPageRoute(&lt;br&gt;
            builder: (context) =&amp;gt; Chat(&lt;br&gt;
              selectedConversation: selectedConv,&lt;br&gt;
 ),&lt;br&gt;
 ));&lt;br&gt;
 },&lt;br&gt;
 ),&lt;br&gt;
);&lt;br&gt;
}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Implementing chat page&lt;/strong&gt;&lt;br&gt;
The chat page is composed of the main historical message list and a message sending bar at the bottom.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ptg392Ga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6cyakgwj3y0fr6we9gw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ptg392Ga--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p6cyakgwj3y0fr6we9gw.png" alt="Image description" width="828" height="1792"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can create a "Chat" class, with "TIMUIKitChat" on its "body", to render the chat page.&lt;br&gt;
It is recommended to provide a "onTapAvatar" callback function, for navigating to the profile page for current contact, which will be introduced in the next step.&lt;/p&gt;

&lt;p&gt;import 'package:flutter/material.dart';&lt;br&gt;
import 'package:tim_ui_kit/tim_ui_kit.dart';&lt;/p&gt;

&lt;p&gt;class Chat extends StatelessWidget {&lt;br&gt;
final V2TimConversation selectedConversation;&lt;br&gt;
const Chat({Key? key, required this.selectedConversation}) : super(key: key);&lt;br&gt;
String? &lt;em&gt;getConvID() {&lt;br&gt;
return selectedConversation.type == 1&lt;br&gt;
 ? selectedConversation.userID&lt;br&gt;
 : selectedConversation.groupID;&lt;br&gt;
}&lt;br&gt;
@override&lt;br&gt;
Widget build(BuildContext context) {&lt;br&gt;
return TIMUIKitChat(&lt;br&gt;
  conversationID: _getConvID() ?? '', // groupID or UserID&lt;br&gt;
  conversationType: selectedConversation.type ?? 1, // Conversation type&lt;br&gt;
  conversationShowName: selectedConversation.showName ?? "", // Conversation display name&lt;br&gt;
  onTapAvatar: (&lt;/em&gt;) {&lt;br&gt;
 Navigator.push(&lt;br&gt;
            context,&lt;br&gt;
 MaterialPageRoute(&lt;br&gt;
             builder: (context) =&amp;gt; UserProfile(userID: userID),&lt;br&gt;
 ));&lt;br&gt;
 }, // Callback for the clicking of the message sender profile photo. This callback can be used with &lt;code&gt;TIMUIKitProfile&lt;/code&gt;.&lt;br&gt;
);&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Implementing profile page&lt;/strong&gt;&lt;br&gt;
This page can show the profile of a specific user and maintain the relationship between the current login user and it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nt3Aoajc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4locjlvs2ysnxbp3is4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nt3Aoajc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4locjlvs2ysnxbp3is4p.png" alt="Image description" width="880" height="953"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ere, you can create a "UserProfile" class, with "TIMUIKitProfile" on its "body", to render the profile page.&lt;br&gt;
The only parameter you have to provide at least is "userID", while this component can generate the profile and relationship maintenance page based on the existence of friendship automatically.&lt;br&gt;
TIPS: Please give priority to use "profileWidgetBuilder", to customize some profile widgets, with "profileWidgetsOrder", determine the vertical sequence, if you tend to customize this page. If this method could not meet your business needs, you may consider using "builder" instead.&lt;/p&gt;

&lt;p&gt;iimport 'package:flutter/material.dart';&lt;br&gt;
import 'package:tim_ui_kit/tim_ui_kit.dart';&lt;/p&gt;

&lt;p&gt;class UserProfile extends StatelessWidget {&lt;br&gt;
final String userID;&lt;br&gt;
const UserProfile({required this.userID, Key? key}) : super(key: key);&lt;/p&gt;

&lt;p&gt;@override&lt;br&gt;
Widget build(BuildContext context) {&lt;br&gt;
return Scaffold(&lt;br&gt;
appBar: AppBar(&lt;br&gt;
title: const Text(&lt;br&gt;
"Message",&lt;br&gt;
style: TextStyle(color: Colors.black),&lt;br&gt;
),&lt;br&gt;
),&lt;br&gt;
body: TIMUIKitProfile(&lt;br&gt;
userID: widget.userID,&lt;br&gt;
),&lt;br&gt;
);&lt;br&gt;
}&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Now, your app can send/receive messages, show the conversation list, and deal with the contact friendship.&lt;/p&gt;

&lt;p&gt;Futhermore&lt;br&gt;
You can use the following components from TUIKit continually to implement the complete IM function quickly and easily.&lt;br&gt;
[TIMUIKitContact]: The contact list page shows the contacts and friends list of a specific user.&lt;br&gt;
[TIMUIKitGroupProfile]: The group profile page, the integrating is basically the same as "TIMUIKitProfile".&lt;br&gt;
[TIMUIKitGroup]: Lists all the group of the specific user.&lt;br&gt;
[TIMUIKitBlackList]: The list contains blocked users.&lt;br&gt;
[TIMUIKitNewContact]: Lists the new contacts applications by other users.&lt;br&gt;
[TIMUIKitSearch]: The search page supports searching contacts, groups, chat records both globally and in specific conversation.&lt;br&gt;
That's all you need to do to integrate the chat module to your Flutter apps.&lt;br&gt;
Hopefully the In-App chat module can help bring you and your customers closer together.&lt;/p&gt;

&lt;p&gt;Find out more at: &lt;a href="https://www.tencentcloud.com/dynamic/blogs/sample-article/100304"&gt;https://www.tencentcloud.com/dynamic/blogs/sample-article/100304&lt;/a&gt;&lt;/p&gt;

</description>
      <category>im</category>
      <category>webdev</category>
      <category>html</category>
      <category>tuikit</category>
    </item>
    <item>
      <title>How to Warm up Your IP Address for Emailing with Tencent Cloud’s Simple Email Service</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Mon, 15 Aug 2022 14:21:09 +0000</pubDate>
      <link>https://dev.to/tencentcloud/how-to-warm-up-your-ip-address-for-emailing-with-tencent-clouds-simple-email-service-18pi</link>
      <guid>https://dev.to/tencentcloud/how-to-warm-up-your-ip-address-for-emailing-with-tencent-clouds-simple-email-service-18pi</guid>
      <description>&lt;p&gt;We’ve previously explored how to optimize the open rate of your marketing email last time. Let’s examine IP warm-up – a key step for email marketing today.&lt;br&gt;
&lt;strong&gt;1. Why is IP warm-up necessary&lt;/strong&gt;&lt;br&gt;
Warm-up is often talked about in the email industry. It is the warming-up of the sender's IP and domain name, a common practice of starting with a small number of emails before starting bulk emailing. The aim is to introduce your sending practices to ISPs (such as Gmail, Hotmail, and QQ Mail) so that they will recognize your sending quality, which helps you build a positive reputation for your domain name and IP.&lt;/p&gt;

&lt;p&gt;If your domain name and IP are not warmed up or have never or barely been used to send emails, sending bulk emails through them will be considered abnormal by the ISP; more often than not, your emails will end up in spam. Therefore, make sure that your IP is warmed up. As long as your IP is trusted by the ISP, you can maintain your reputation even if the number of sent messages greatly fluctuates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. How to warm up your IP&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;&lt;strong&gt;Step 1. Set up your identity verification&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Before the warm-up, make sure that you have performed SPF, DKIM, MX, and DMARC validation. For more information, visit &lt;a href="https://www.tencentcloud.com/document/product/1084/40180"&gt;https://www.tencentcloud.com/document/product/1084/40180&lt;/a&gt;. The ISP will have your emails delivered only after the validation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 2. Select your recipients during the warm-up&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Warming up an IP is to email a few addresses through the IP and slowly increase the number of emails. It is important that you select the right recipients. Keep a clean list of recipients; that is, avoid emailing invalid addresses. Also, keep the list active, so as to get a good open rate and click rate.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 3. Send proper content&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
Be formal in your content and do not muddle through your warm-up with just an image or a few sentences. The whole warm-up process should be real or real-world-like. For triggered domain names, use content such as [welcome], [notification], and [e-commerce transaction] to guide user interactions (such as clicking links and replying to the email). For bulk emailing domain names, formulate a delicate marketing template, so that the content is less likely to be identified as spam.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Step 4. Determine the send volume and frequency&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
The warm-up usually takes about a month. Generally speaking, you can start with 1,000–2,000 emails per IP per day and slowly increase the volume. Make sure that the numbers of emails from different ISPs are even as much as possible. Pay attention to the email feedback. The better the feedback, the looser the requirements of ISPs, and the higher the number of emails that can be sent.&lt;br&gt;
During the warm-up, keep a close eye on the delivery, bounce, and spam folder. Stop sending emails as soon as they are found to be blocked and continue the sending of a smaller number of emails the next day.&lt;/p&gt;

&lt;p&gt;Stay tuned for our next topic with best practice sharing on marketing email design!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>edm</category>
    </item>
    <item>
      <title>How to Increase Your Marketing Email Open Rate with Tencent Cloud’s Simple Email Service</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Thu, 11 Aug 2022 06:53:00 +0000</pubDate>
      <link>https://dev.to/tencentcloud/how-to-increase-your-marketing-email-open-rate-with-tencent-clouds-simple-email-service-1cec</link>
      <guid>https://dev.to/tencentcloud/how-to-increase-your-marketing-email-open-rate-with-tencent-clouds-simple-email-service-1cec</guid>
      <description>&lt;p&gt;The email open rate is of great concern to EDM marketers as well as one of the most crucial metrics for evaluating the effectiveness of their marketing. Check out the essential guidelines to enhance the open rate of your marketing email!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Find the optimum send time&lt;/strong&gt;&lt;br&gt;
23.63% of the emails are opened within the first hour after delivery, after which the open rate slumps as time goes by. Therefore, it is important to understand the habits of your recipients, as emails sent to them when they are using a computer or mobile phone are more likely to be opened.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Use the right sender's name and address&lt;/strong&gt;&lt;br&gt;
The sender's name and address matter, as they tell the recipients who sent the email. Statistics have shown that 73% of email recipients decide whether to open an email based on the sender's name.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Create an appealing email subject line&lt;/strong&gt;&lt;br&gt;
A survey by a data research agency has shown that 69% of email recipients decide whether to open an email based on the subject line. Choose a subject that is relevant to your offering. This can make recipients feel connected and confident.&lt;br&gt;
Add the name, city, or other variables of your recipients to the subject line to draw their attention. This can be easily done with Tencent Cloud Simple Email Service (SES), which allows adding variables during bulk emailing. For more information, see &lt;a href="https://www.tencentcloud.com/products/ses"&gt;https://www.tencentcloud.com/products/ses&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Perform A/B testing&lt;/strong&gt;&lt;br&gt;
A/B testing helps you figure out a better email design by comparing the test results. For example, to determine the best email subject line, you can randomly split your recipients into two groups and email them in two different ways of A and B.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Determine the appropriate send frequency&lt;/strong&gt;&lt;br&gt;
You can query the data about your previous bulk email sends and group your recipients by email open frequency. Then you will have a high-frequency group and a low-frequency group. You can email the former frequently but the latter less frequently.&lt;/p&gt;

&lt;p&gt;For more details, please visit: &lt;a href="https://www.tencentcloud.com/dynamic/blogs/sample-article/100320"&gt;https://www.tencentcloud.com/dynamic/blogs/sample-article/100320&lt;/a&gt;&lt;br&gt;
Our next topic will focus on how to warn up your IP address for emailing. Stay tuned!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>edm</category>
      <category>html</category>
      <category>design</category>
    </item>
    <item>
      <title>Tencent Cloud Lighthouse Instance Just Right for You</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Tue, 09 Aug 2022 03:31:44 +0000</pubDate>
      <link>https://dev.to/tencentcloud/tencent-cloud-lighthouse-instance-just-right-for-you-3aa5</link>
      <guid>https://dev.to/tencentcloud/tencent-cloud-lighthouse-instance-just-right-for-you-3aa5</guid>
      <description>&lt;p&gt;&lt;strong&gt;1. What is Tencent Cloud Lighthouse&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A Tencent Cloud Lighthouse instance is just as easy to create, network-isolated, and stable as a Tencent Cloud CVM (Cloud Virtual Machine) instance. In addition, it offers differentiated yet targeted capabilities for SMEs and individual developers, such as ease of mastery with fewer concepts/parameters and more developer/application-friendly features.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Ease of Mastery with Fewer Concepts&lt;/strong&gt;&lt;br&gt;
Lighthouse is designed with fewer concepts than CVM for you to master it more effortlessly. Furthermore, its technical implementation is transparently simplified to just two core parameters: application environment and instance bundle. The former is delivered as application and system images, while the latter includes the bundle type and fee information and internally encapsulates a diversity of CVM concepts, including AZ, model, VPC, bandwidth, and data transfer plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. More Developer/Application-Friendly Features&lt;/strong&gt;&lt;br&gt;
Lighthouse is inherently designed and developed to be closer to applications and developers. Unlike CVM, it is more about application deployment rather than resource creation; therefore, you can always select an appropriate image first and then configure resource parameters, easily and quickly.&lt;br&gt;
Lighthouse works well with various mainstream applications that can be swiftly created and managed. For SMEs and individual developers, it offers a selection of popular application images, such as WordPress, LAMP, Node.js, and ASP.NET.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Virtualization and Quick Creation&lt;/strong&gt;&lt;br&gt;
Based on Tencent Cloud VStation's powerful capabilities of centrally scheduling and managing heterogeneous resources (KVM, bare metal, microVM, etc.), Lighthouse features fast and smart scheduling and high reliability, especially when it comes to large-scale clusters. As Lighthouse is delivered mainly through application images, Tencent Cloud CBS snapshotting can be readily used to create a Lighthouse instance in seconds when a snapshot rollback is triggered.&lt;/p&gt;

&lt;p&gt;Read more at: &lt;a href="https://www.tencentcloud.com/dynamic/insights/sample-article/100316"&gt;https://www.tencentcloud.com/dynamic/insights/sample-article/100316&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>server</category>
      <category>devops</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Tencent Cloud IM：Chat API For Real-Time In-App Communication</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Wed, 03 Aug 2022 02:30:00 +0000</pubDate>
      <link>https://dev.to/tencentcloud/tencent-cloud-imchat-api-for-real-time-in-app-communication-1n41</link>
      <guid>https://dev.to/tencentcloud/tencent-cloud-imchat-api-for-real-time-in-app-communication-1n41</guid>
      <description>&lt;p&gt;&lt;strong&gt;What is Tencent Cloud IM？&lt;/strong&gt;&lt;br&gt;
**Tencent Cloud IM（ Instant Messaging ）provides Chat API for apps and websites. IM integrates diverse chat capabilities such as one-to-one chat, group chat, chat room, and system notification into its SDKs and UIkit components for various platforms to help you develop your business quickly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---dimeqzC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpz66gyaxt7mvcnabg5y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---dimeqzC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpz66gyaxt7mvcnabg5y.png" alt="Image description" width="880" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What can you do with Tencent IM？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Chat in-App&lt;/strong&gt;&lt;br&gt;
- IM provides chat API for apps and websites, supporting several message types such as text, emojis, images, short audio, and short videos, which can increase user activity.&lt;br&gt;
- IM supports various group types such as private groups, public groups, and chat rooms, which meet the requirements for specific group chat scenarios and diversified social interaction techniques. &lt;a href="https://intl.cloud.tencent.com/document/product/1047/45914?lang=en&amp;amp;pg=&amp;amp;from=dev"&gt;https://intl.cloud.tencent.com/document/product/1047/45914?lang=en&amp;amp;pg=&amp;amp;from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6lBr7GGL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1u2582cao8qdwhfxkhz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6lBr7GGL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1u2582cao8qdwhfxkhz7.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Interactive Live Streaming&lt;/strong&gt;&lt;br&gt;
- IM supports chatting through on-screen comments.&lt;br&gt;
- IM supports special messages such as giving “likes”, gifts, and rewards by using custom messages. &lt;br&gt;
- IM provides audio/video chat rooms with no user count limits and enables smooth chat in rooms with millions of users.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W4j1Ksak--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99af3u4muawhg6ier8xq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W4j1Ksak--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99af3u4muawhg6ier8xq.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Chat in-Game&lt;/strong&gt;&lt;br&gt;
- IM supports diverse in-game message types such as text, emoji, image, short audio, and short video, which can stimulate players’ activity and increase their participation rate. &lt;br&gt;
- IM has global access points and cache nodes in the Asia Pacific, North America, Europe, Middle East, Africa, and Latin America, which implement nearby access and ensure the quality of communication for players.&lt;br&gt;
- In addition to group profile photo, group nickname, group description, group member profile, and group member nickname, IM also supports a maximum of 20 custom fields for the differentiated display of in-game roles. &lt;a href="https://intl.cloud.tencent.com/document/product/1047/41656?from=dev%C2%A0https://intl.cloud.tencent.com/document/product/1047/45908?from=dev"&gt;https://intl.cloud.tencent.com/document/product/1047/41656?from=dev https://intl.cloud.tencent.com/document/product/1047/45908?from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6eWPkRtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ug4gkaaixx6qesqxvfyv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6eWPkRtB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ug4gkaaixx6qesqxvfyv.png" alt="Image description" width="880" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. More Scenarios&lt;/strong&gt;&lt;br&gt;
 IM is also applicable in various scenarios including online education, healthcare, customer service, meeting. For more scenarios, please see&lt;br&gt;
&lt;a href="https://intl.cloud.tencent.com/products/im?lang=en&amp;amp;pg=&amp;amp;from=dev"&gt;https://intl.cloud.tencent.com/products/im?lang=en&amp;amp;pg=&amp;amp;from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Tencent Cloud IM？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Expert in chat SDK service&lt;/strong&gt;&lt;br&gt;
Tencent is the first and largest developer of chat service in mainland China. QQ and Weiixin, both developed by Tencent, have 1.8 billion monthly active users. Tencent has 23 years of experience in chat development. &lt;a href="https://intl.cloud.tencent.com/document/product/1047/33515https://intl.cloud.tencent.com/products/im?lang=en&amp;amp;pg=&amp;amp;from=dev"&gt;https://intl.cloud.tencent.com/document/product/1047/33515https://intl.cloud.tencent.com/products/im?lang=en&amp;amp;pg=&amp;amp;from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Independent IDC and global access&lt;/strong&gt;&lt;br&gt;
IM has independent data storage nodes in Singapore, Germany, India and South Korea as well as 2100+ global access points and cache nodes in the Asia Pacific, North America, Europe, Middle East, Africa, and Latin America to achieve worldwide reach. These nodes enable messages to be delivered globally in 200ms on average.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Easy and Quick Integration&lt;/strong&gt;&lt;br&gt;
 You can run the demo in just ten minutes. By implementing the UI features based on TUIKit and calling the corresponding APIs of the IM SDK, you can build your own IM application in just one day. &lt;a href="https://intl.cloud.tencent.com/document/product/1047/45914?from=dev"&gt;https://intl.cloud.tencent.com/document/product/1047/45914?from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Comprehensive API platform&lt;/strong&gt;&lt;br&gt;
 IM API platform covers a comprehensive range, including iOS, Android, Web, Unity, Unreal Engine, C, Flutter, and Electron. &lt;a href="https://intl.cloud.tencent.com/document/product/1047/34552?from=dev"&gt;https://intl.cloud.tencent.com/document/product/1047/34552?from=dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Contact Us&lt;br&gt;
Join the Tencent Cloud IM group for：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reliable technical support &lt;/li&gt;
&lt;li&gt;Product details&lt;/li&gt;
&lt;li&gt;Constant exchange of ideas
Telegram group: &lt;a href="https://t.me/tencent_imsdk"&gt;https://t.me/tencent_imsdk&lt;/a&gt;
Discord group: &lt;a href="https://discord.gg/8EmN2ma25W"&gt;https://discord.gg/8EmN2ma25W&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>instantmessaging</category>
      <category>webdev</category>
      <category>api</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Do you know about Tencent Cloud?</title>
      <dc:creator>Denize Chan</dc:creator>
      <pubDate>Wed, 03 Aug 2022 02:16:00 +0000</pubDate>
      <link>https://dev.to/tencentcloud/do-you-know-about-tencent-cloud-5cm2</link>
      <guid>https://dev.to/tencentcloud/do-you-know-about-tencent-cloud-5cm2</guid>
      <description>&lt;p&gt;Tencent Cloud is the cloud business of global technology company Tencent with headquarters in Shenzhen, China. It provides users and businesses around the world with stable and cloud products and services, leveraging technological advancements such as cloud computing, big data analytics, AI, IoT and network security.&lt;/p&gt;

&lt;p&gt;Tencent Cloud is a service that meets the needs of industries across the board, including the fields of education, finance, healthcare, gaming, media and entertainment, property, retail, travel and transportation. It also strives to help overseas businesses enter the China market through its China Connect solution and help Chinese enterprises to go global.&lt;/p&gt;

&lt;p&gt;Tencent Cloud currently operates 70 availability zones in 26 geographical regions around the world, providing a strong infrastructure network that enables enterprises to expand across the globe.&lt;/p&gt;

&lt;p&gt;Tencent Cloud offers over 400 cloud products &amp;amp; solutions to support enterprise digital transformation and is particularly strong in terms of audio &amp;amp; video, game and financial services solutions, as well as database solutions and security performance. It is also recognized by many top global analyst firms, including Gartner, IDC, Forrester, Frost &amp;amp; Sullivan and more.&lt;/p&gt;

&lt;p&gt;Find out more at &lt;a href="https://www.tencentcloud.com/"&gt;https://www.tencentcloud.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cloud</category>
      <category>tencentcloud</category>
    </item>
  </channel>
</rss>
