即时通讯能力在业务系统中已经从聊天工具扩展为订单通知、群组协作、直播互动等场景的基础设施。Spring Boot项目接入腾讯云IM,通常采用服务端处理账号体系和群组管理、客户端SDK负责长连接和实时收发的方案。这样既能复用腾讯云IM的消息可靠性投递和多端同步能力,又不必自己维护复杂的TCP长连接集群。本文重点围绕单聊和群聊两个核心场景,给出服务端和前端配合的落地步骤。

腾讯云IM的调用链路可以拆成三块:控制台应用管理、服务端REST API、客户端SDK。服务端通过REST API完成用户导入、群组创建和主动消息发送,客户端通过SDK完成登录、会话和消息监听。接下来从基础结构切入,先说明配置和依赖,再逐步实现单聊与群聊能力。
一、控制台配置与项目依赖
在腾讯云IM控制台创建应用后,会得到SDKAppID和密钥。SDKAppID是应用的唯一标识,密钥用于生成UserSig,必须保存在服务端,不能下发到客户端。管理员账号可以指定为admin,后续所有REST调用都使用管理员UserSig完成身份校验。创建应用时还要确认已开通单聊和群组功能,因为部分计费项和功能开关会直接影响API可用性。
项目依赖方面,Spring Boot使用spring-boot-starter-web提供HTTP接口,RestTemplate做REST调用。UserSig建议直接引入腾讯云官方工具类,避免手写HMAC算法出错。核心依赖如下:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.github.tencentyun</groupId> <artifactId>tls-sig-api-v2</artifactId> <version>1.1</version> </dependency>
配置放在application.yml中,方便区分环境。SDKAppID、密钥、管理员账号和IM REST地址都通过配置注入,不要硬编码在Java类里。下面的配置结构可作为基础模板:
tencent:
im:
sdk-app-id: 1400000000
secret-key: your-secret-key
admin-user: admin
base-url: https://console.tim.qq.com
实际部署时,secret-key建议通过环境变量或配置中心覆盖,避免提交到代码仓库。管理员账号可以单独维护,登录凭证的有效期根据安全策略调整,通常服务端内部调用使用24小时有效期即可。
二、UserSig生成与REST调用基础封装
UserSig本质是腾讯云IM的用户登录凭证,服务端REST API也复用它做请求鉴权。生成UserSig的入参包括SDKAppID、用户ID和密钥,有效期可以按业务需求设置,管理员账号一般给24小时或更长,避免高频刷新带来额外复杂度。这里封装一个UserSigService,注入SDKAppID和密钥,对外提供统一生成方法。
import com.tencentyun.TLSSigAPIv2;
public class UserSigService {
private final long sdkAppId;
private final String secretKey;
public UserSigService(long sdkAppId, String secretKey) {
this.sdkAppId = sdkAppId;
this.secretKey = secretKey;
}
public String createAdminUserSig(String adminUser, int expireSeconds) {
TLSSigAPIv2 api = new TLSSigAPIv2(sdkAppId, secretKey);
return api.genUserSig(adminUser, expireSeconds);
}
}
REST调用还要解决URL拼接和JSON请求体构造。腾讯云IM REST接口固定使用HTTPS,基础地址为console.tim.qq.com,每个请求都需要附带sdkappid、identifier、usersig、random和contenttype五个参数。random建议使用SecureRandom生成,不要用固定值,否则可能触发限流和重放风险。通用客户端可以这样封装:
import org.springframework.http.*;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
@Component
public class ImRestClient {
private final RestTemplate restTemplate = new RestTemplate();
public String post(String url, String body) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(body, headers);
ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, entity, String.class);
return response.getBody();
}
public String buildUrl(String path, long sdkAppId, String identifier, String userSig) {
int random = new java.security.SecureRandom().nextInt(99999999);
return "https://console.tim.qq.com" + path
+ "?sdkappid=" + sdkAppId
+ "&identifier=" + identifier
+ "&usersig=" + userSig
+ "&random=" + random
+ "&contenttype=json";
}
}
实际调用时,如果接口返回错误码,需要根据腾讯云IM的错误码文档进行排查。常见错误包括UserSig过期、账号不存在、群组不存在等。建议在封装层对响应体做统一解析,把ActionStatus和ErrorCode抛给业务层处理。
三、单聊功能落地
单聊需要先把业务用户导入腾讯云IM,否则客户端登录会报用户不存在。导入账号调用account_import接口,可以同时设置昵称和头像。用户注册成功后同步调用一次即可,离线或已存在时重复导入会覆盖资料。下面是一个导入用户的Service示例,直接复用前面封装好的UserSig和REST客户端。
@Service
public class ImUserService {
private final UserSigService userSigService;
private final ImRestClient imRestClient;
private final long sdkAppId;
private final String adminUser;
public ImUserService(UserSigService userSigService, ImRestClient imRestClient) {
this.userSigService = userSigService;
this.imRestClient = imRestClient;
this.sdkAppId = 1400000000L;
this.adminUser = "admin";
}
public void importUser(String userId, String nickName) {
String userSig = userSigService.createAdminUserSig(adminUser, 86400);
String url = imRestClient.buildUrl("/v4/im_open_login_svc/account_import",
sdkAppId, adminUser, userSig);
String body = "{\"UserID\":\"" + userId + "\",\"Nick\":\"" + nickName + "\",\"FaceUrl\":\"\"}";
String response = imRestClient.post(url, body);
System.out.println(response);
}
}
导入用户后,客户端登录即可互相发单聊消息。服务端主动发单聊消息则使用openim/sendmsg接口,适用于系统通知、订单状态变更等无需对方在线也能落地的场景。注意MsgBody是数组结构,这里用TIMTextElem作为文本消息示例。
@Service
public class ImMessageService {
private final UserSigService userSigService;
private final ImRestClient imRestClient;
private final long sdkAppId;
private final String adminUser;
public void sendC2CText(String fromUserId, String toUserId, String text) {
String userSig = userSigService.createAdminUserSig(adminUser, 86400);
String url = imRestClient.buildUrl("/v4/openim/sendmsg",
sdkAppId, adminUser, userSig);
String body = "{"
+ "\"SyncOtherMachine\":2,"
+ "\"From_Account\":\"" + fromUserId + "\","
+ "\"To_Account\":\"" + toUserId + "\","
+ "\"MsgRandom\":" + System.currentTimeMillis() % 100000000 + ","
+ "\"MsgBody\":[{"
+ "\"MsgType\":\"TIMTextElem\","
+ "\"MsgContent\":{\"Text\":\"" + text + "\"}"
+ "}]"
+ "}";
imRestClient.post(url, body);
}
}
SyncOtherMachine参数控制是否同步到发送方的其他设备,取值2表示不同步,取值1表示同步。服务端主动发消息时要合理设置From_Account,它会在消息列表里展示为消息的发送者。对于业务系统常见的客服通知、物流提醒,可以统一使用一个系统管理员账号作为发送方。
四、群聊功能落地
群聊接入前要先明确群类型。腾讯云IM的群组分为Public公开群、Private私有群、ChatRoom聊天室、AVChatRoom直播聊天室等。普通群适合成员稳定、需要消息漫游的业务,直播聊天室支持超大人数但历史消息保存较弱。Spring Boot项目中可以先提供创建群组的方法,后续再按业务选择群类型。
public void createGroup(String ownerId, String groupName, String groupType) {
String userSig = userSigService.createAdminUserSig(adminUser, 86400);
String url = imRestClient.buildUrl("/v4/group_open_http_svc/create_group",
sdkAppId, adminUser, userSig);
String body = "{"
+ "\"Owner_Account\":\"" + ownerId + "\","
+ "\"Type\":\"" + groupType + "\","
+ "\"Name\":\"" + groupName + "\""
+ "}";
imRestClient.post(url, body);
}
群创建成功后,客户端可以通过群ID发送群消息。服务端也可以调用group_open_http_svc/send_group_msg接口主动推送群消息。请求体包含GroupId、From_Account、MsgBody等字段,结构与单聊类似,但无需To_Account,改为GroupId。实际业务中服务端主动发群消息常用于活动开始提醒、群公告同步等运营动作。
群成员管理也是整合过程中容易忽略的部分。创建群组后,如果后续用户加入,可以调用add_group_member接口批量导入成员,避免客户端加入时出现异常。对于私有群,还可以结合腾讯云IM的回调功能,在用户加入群组时同步业务侧的状态。群类型的选择要和产品确认,例如直播聊天室不要频繁拉取全量成员列表,否则性能会明显下降。
五、前端接入与回调配置
前端安装腾讯云IM官方SDK,Web端可以使用@tencentcloud/chat。初始化时传入SDKAppID,然后注册SDK_READY和MESSAGE_RECEIVED事件。登录需要的UserSig应由服务端生成后返回给前端,不能直接在客户端生成,否则密钥泄露风险很高。
import TIM from '@tencentcloud/chat';
const tim = TIM.create({ SDKAppID: 1400000000 });
tim.on(TIM.EVENT.SDK_READY, function(event) {
console.log('SDK ready', event.name);
});
tim.on(TIM.EVENT.MESSAGE_RECEIVED, function(event) {
const messageList = event.data;
messageList.forEach(function(message) {
if (message.type === TIM.TYPES.MSG_TEXT) {
console.log(message.payload.text);
}
});
});
tim.login({ userID: 'user_001', userSig: 'server-generated-user-sig' })
.then(function(imResponse) {
console.log('登录成功', imResponse.data);
})
.catch(function(imError) {
console.error('登录失败', imError);
});
function sendTextMessage(targetId, text, type) {
const conversationType = type === 'group' ? TIM.TYPES.CONV_GROUP : TIM.TYPES.CONV_C2C;
const options = {
to: targetId,
conversationType: conversationType,
payload: { text: text }
};
const message = tim.createTextMessage(options);
return tim.sendMessage(message);
}
发送单聊和群聊在SDK层通过conversationType区分。TIM.TYPES.CONV_C2C表示单聊,TIM.TYPES.CONV_GROUP表示群聊。文本消息通过createTextMessage构造,发送后可以在Promise回调中确认发送成功。上面的示例已展示两种会话类型的切换方式。
如果业务需要监听用户资料变更、群事件或消息回调,可以在腾讯云IM控制台配置HTTP回调地址,指向Spring Boot的公开接口。回调接口需能接收JSON字节流并返回ActionStatus OK。生产环境建议对回调来源做校验,如验证腾讯云回调中的签名字段或限制来源IP,避免伪造回调。基础回调接口示例如下:
@RestController
public class ImCallbackController {
@PostMapping("/im/callback")
public String handleCallback(@RequestBody String payload) {
System.out.println(payload);
return "{\"ActionStatus\":\"OK\"}";
}
}
整合完成后,可以先在测试环境跑通一条完整消息链路:服务端导入用户、生成UserSig并返回前端、前端登录后用SDK发送单聊消息,再创建一个群组并验证群消息收发。整条链路稳定后,再根据业务需求补充消息撤回、已读回执、自定义消息类型和离线推送等高级能力。
Spring Boot腾讯云IM即时通讯修改时间:2026-10-02 18:43:06