跳到主要内容

Go 服务端集成

安装​

Go 1.21+。在新目录执行安装命令,保存为 classroom.go,配置环境变量后运行 go run .。已有 Go module 只需执行 go get。

go mod init example.com/eduskit-demo
go get github.com/eduskit/server-sdk-go@v0.1.5

每次调用均检查 error。业务请求的 context.Context 应沿调用链传入;取消或超时后不要继续读取可能为空的返回数据。

创建课堂并签发学生凭证​

先配置服务端环境变量。本例使用独立老师和学生账号,头像 URL 为示例值,实际接入时替换为可访问的资源。每次运行都会创建新课堂;originId 仅使用户注册幂等。

package main

import (
"context"
"errors"
"fmt"
"os"
"time"

eduskit "github.com/eduskit/server-sdk-go"
)

func createDemoClassroom(ctx context.Context) (map[string]any, error) {
config := map[string]string{}
for _, key := range []string{"EDU_SERVER_URL", "EDU_APP_ID", "EDU_APP_KEY", "EDU_APP_SECRET"} {
config[key] = os.Getenv(key)
if config[key] == "" {
return nil, fmt.Errorf("missing %s", key)
}
}
sdk := eduskit.New(eduskit.Options{
Timeout: 10 * time.Second,
Client: &eduskit.ClientConfig{
BaseURL: config["EDU_SERVER_URL"], AppID: config["EDU_APP_ID"],
AppKey: config["EDU_APP_KEY"], AppSecret: config["EDU_APP_SECRET"],
},
})
client, err := sdk.Client()
if err != nil {
return nil, err
}
teacher, err := client.Users.Register(ctx, map[string]any{
"originId": "demo-teacher-001", "nickname": "Teacher",
"avatar": "https://example.com/teacher.png",
})
if err != nil {
return nil, err
}
student, err := client.Users.Register(ctx, map[string]any{
"originId": "demo-student-001", "nickname": "Student",
"avatar": "https://example.com/student.png",
})
if err != nil {
return nil, err
}
classroom, err := client.Classrooms.Create(ctx, map[string]any{
"name": "SDK integration",
"startsAt": time.Now().UTC().Add(15 * time.Minute).Format(time.RFC3339),
"durationMinutes": 60,
"teacherEduUserId": teacher["eduUserId"],
"studentEduUserIds": []any{student["eduUserId"]},
"joinPolicy": "invite_only",
})
if err != nil {
return nil, err
}
token, err := client.Auth.IssueToken(ctx, map[string]any{
"eduUserId": student["eduUserId"], "originId": "demo-student-001", "expiresIn": 3600,
})
if err != nil {
return nil, err
}
return map[string]any{
"appId": token["appId"], "classroomId": classroom["classroomId"],
"userId": student["eduUserId"], "userToken": token["accessToken"],
"expiresAt": token["expiresAt"],
}, nil
}

func main() {
entry, err := createDemoClassroom(context.Background())
if err != nil {
var sdkErr *eduskit.Error
if errors.As(err, &sdkErr) {
fmt.Fprintln(os.Stderr, sdkErr.ErrorCode, sdkErr.Status, sdkErr.TraceID, sdkErr.Source)
} else {
fmt.Fprintln(os.Stderr, err)
}
os.Exit(1)
}
fmt.Println(entry["classroomId"], entry["userId"])
}

将返回的 userToken 通过业务进课接口交给已通过鉴权的学生。正式系统在排课时创建课堂,在用户进课时签发 Token。

调用约定​

sdk.Client() / sdk.WhiteboardClient() 返回客户端和错误。HTTP 方法使用 PascalCase,返回 map[string]any。超时使用 time.Duration。

成员、权限、课件及上下课方法见课堂 API。白板录制与转码见白板服务端集成。错误与排查说明 HTTP 失败、签名失败和重试边界。

应用业务与租户管理接口​

源码构建的 client 提供 50 个应用凭证 HTTP 路由,包含用户、课堂、课件库、直播素材与诊断。参数与返回结构见应用业务接口,完整流程见业务操作示例。独立的租户管理客户端 使用租户会话管理账号、应用、仪表盘和计费。新增方法需要对应版本的 server-api 与 SDK 源码构建;公开包 0.1.5 不包含这些新增方法。