服务端

调用方式

更新时间: 2024/06/06 15:27:47

应用服务端调用 API 向网易云信 RTC 服务端发起的请求需遵循固定的请求结构和请求方式。

  • 网易云信所有接口均支持通过 HTTPS 协议进行通信,保障更高的安全性。
  • 请求及返回结果均使用 UTF-8 字符集编码。

请求概述

服务端 API 原理图.png
  • 通信协议:RTC 服务端 API 使用 HTTP/HTTPS 网络请求协议。

  • 请求方式:应用服务端向 RTC 服务端发起的请求支持 POST、DELETE、GET 三种方式,分别对应资源的增加、删除、修改和查询操作。

  • 服务地址:网易云信 RTC 服务端 API 的接入地址为 https://logic-dev.netease.im/v2/api

    上述接入地址的域名(logic-dev.netease.im)属于国内数据中心域名。如果您的应用主要服务于海外用户,需将域名设置为海外数据中心域名(call-prd-ap.netease.im),相应的海外接入地址为 https://call-prd-ap.netease.im/v2/api。更多海外数据中心接入相关说明,请参考 出海解决方案

  • 请求结构:RTC 服务端 API 请求结构主要由下表所示三部分组成。

    组成部分
    描述
    URL 指向具体的业务请求,请参考各 API 文档
    如果您的应用主要服务于海外用户,需将 URL 中的国内数据中心域名(logic-dev.netease.im)替换为海外数据中心域名(call-prd-ap.netease.im)
    Header 请求头,包含网易云信 App Key、CheckSum 等在内的 公共请求参数,用于鉴权。应用服务端请求 RTC 服务端的所有 API 调用均采用 相同 的 Header 公共请求参数配置
    Body 请求体,包含 API 对应的业务参数,具体参考各 API 文档的 请求参数 小节

请求头 Header

Header 中包括用于鉴权的相关公共参数,用于标识用户和接口签名。如非必要,每个单独的接口文档中不再对这些参数进行说明,但每次请求均需要携带这些参数,才能正常发起请求。

参数名称 类型 是否必选 示例 说明
AppKey String b2e***fcc155e7d26c4 网易云信控制台为应用分配的 AppKey。获取方法请参考 创建应用并获取 AppKey
Nonce String 8dfdb33d2840 随机数,最大长度 128 个字符。
CurTime String 1443592222 当前 UTC 时间戳,从 1970 年 1 月 1 日 0 点 0 分 0 秒开始到现在(指发起请求瞬间的前后 5 分钟内)的秒数。数据类型为 String。请求 Header 中的 CurTime 字段需要传入正确的 Unix 时间戳。调用服务端接口前,请确认调用方的本地服务器时间正确,否则可能会导致 CurTime 字段传参错误,并收到报错 414。
CheckSum String b404199cdb06d20xxxdc61016d
  • CheckSum = sha1(AppSecret + Nonce + CurTime)。将 AppSecret、Nonce 和 CurTime 三个参数拼接的字符串经过 SHA1 哈希计算,并将结果转化成 16 进制字符。CheckSum 的值为 String 格式,小写。
  • 出于安全性考虑,每个 CheckSum 的 有效期 为 CurTime 时间开始之后的 5 分钟 内。建议每次请求都生成新的 CheckSum,同时请确认发起请求的服务器与标准时间同步,例如 NTP 服务。
  • CheckSum 检验失败时会返回 401 错误码,更多错误码信息请参考 错误码

请妥善保管用于计算 CheckSumAppSecret,可在应用服务器存储和使用,但不应存储或传递到客户端,也不应在网页等前端代码中嵌入。

CheckSum 计算

您可以参考以下代码计算 CheckSum。

Java
Javapackage com.netease.im.rtctoken;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class RestApiAuth {
    // 计算并获取 CheckSum
    public static String getChecksum(String appSecret, String nonce, long curTime) {
        return sha1(appSecret + nonce + curTime);
    }

    // 对输入字符串进行 SHA1 哈希计算
    private static String sha1(String input) {
        try {
            MessageDigest mDigest = MessageDigest.getInstance("SHA-1");
            byte[] result = mDigest.digest(input.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte b : result) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
Node.js
Node.jsconst crypto = require('crypto');

var GetChecksum = function (appSecret, nonce, curTime) {
    return sha1(`${appSecret}${nonce}${curTime}`);
}

const sha1 = function (input) {
    const sha1 = crypto.createHash('sha1');
    sha1.update(input, 'utf8');
    return sha1.digest('hex');
}
Go
Golangpackage token

import (
    "crypto/sha1"
    "fmt"
)

func GetChecksum(appSecret, nonce string, curtime int64) string {
    raw := fmt.Sprintf("%s%s%d", appSecret, nonce, curtime)
    return fmt.Sprintf("%x", sha1.Sum([]byte(raw)))
}

PHP
PHP<?php
function getChecksum(string $appSecret, string $nonce, int $curtime):string {
    return sha1($appSecret . $nonce . $curtime);
}
?>
Python
Pythonimport hashlib

def get_checksum(app_secret: str, nonce: str, timestamp: int):
    return hashlib.sha1(f'{app_secret}{nonce}{timestamp}'.encode()).hexdigest()
C#
C#using System.Security.Cryptography;
using System.Text;

namespace TokenBuilder
{
    public class RestApiAuth
    {
        public static string GetChecksum(string appSecret, string nonce, long curtime)
        {
            return ComputeSHA1($"{appSecret}{nonce}{curtime}");
        }
        private static string ComputeSHA1(string input)
        {
            using var sha1 = SHA1.Create();
            var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
            var sb = new StringBuilder(hash.Length * 2);

            foreach (byte b in hash)
            {
                sb.Append(b.ToString("x2"));
            }

            return sb.ToString();
        }
    }
}
C++
C++#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <openssl/sha.h>

std::string sha1(const std::string &input)
{
    unsigned char hash[SHA_DIGEST_LENGTH];
    SHA1(reinterpret_cast<const unsigned char *>(input.c_str()), input.length(), hash);
    std::ostringstream oss;
    oss << std::hex << std::setfill('0');
    for (auto c : hash)
    {
        oss << std::setw(2) << static_cast<int>(c);
    }
    return oss.str();
}

std::string getChecksum(const std::string appSecret, std::string nonce, long curtime)
{
    return sha1(appSecret + nonce + std::to_string(curtime));
}

请求体 Body

服务端 API 请求的 Content-Typeapplication/json。传入的 Body 必须为 JSON 格式。

返回结果

API 返回结果的格式统一。Header 中返回 2xx HTTP 状态码代表接口调用成功。Header 中返回 4xx 或 5xx HTTP 状态码代表接口调用失败。调用失败时,部分接口会同时在 Body 中返回该调用的相关错误信息供您排查问题。

正常返回示例

接口调用成功后会返回接口返回参数,这样的返回为正常返回。正常返回的 HTTP Header 中的状态码为 2xx。

正常返回示例如下:

JSON{
    "code": 200,
    "cid": 12345
}

异常返回示例

接口调用出错后,会返回错误码、错误信息,这样的返回为异常返回。HTTP Header 中的状态码为 4xx 或者 5xx。部分接口会在 Body 中返回具体的业务错误码和错误信息供您排查问题。

您可以根据接口调用后返回的错误码,参考 Header 中的状态码Body 中的错误码排查问题。当您无法排查问题时,可以 提交工单 联系网易云信技术支持工程师。

异常返回示例如下:

此文档是否对你有帮助?
有帮助
去反馈
  • 请求概述
  • 请求头 Header
  • CheckSum 计算
  • 请求体 Body
  • 返回结果
  • 正常返回示例
  • 异常返回示例