123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- package com.ym.controller;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONObject;
- import com.google.common.collect.Lists;
- import com.microsvc.toolkit.middleware.im.ImPluginContext;
- import com.microsvc.toolkit.middleware.im.impl.TencentCloudImPlugin;
- import com.microsvc.toolkit.middleware.live.LivePluginContext;
- import com.microsvc.toolkit.middleware.live.LivePluginService;
- import com.microsvc.toolkit.middleware.live.impl.TencentCloudLivePlugin;
- import com.ym.common.BaseResponse;
- import com.ym.mec.auth.api.entity.SysUser;
- import com.ym.mec.biz.dal.dao.TeacherDao;
- import com.ym.mec.biz.dal.dto.TencentData;
- import com.ym.mec.biz.dal.dto.TencentImCallbackResult;
- import com.ym.mec.biz.dal.dto.im.BasicUserInfo;
- import com.ym.mec.biz.dal.enums.ETencentImCallbackCommand;
- import com.ym.mec.biz.dal.enums.im.ClientEnum;
- import com.ym.mec.biz.dal.wrapper.ImGroupWrapper;
- import com.ym.mec.biz.service.ImLiveBroadcastRoomService;
- import com.ym.mec.biz.service.SysUserService;
- import com.ym.mec.biz.service.im.ImGroupCoreService;
- import com.ym.mec.common.entity.ImUserModel;
- import com.ym.mec.common.entity.ImUserState;
- import com.ym.service.LiveRoomService;
- import com.ym.service.RoomService;
- import com.ym.service.UserService;
- import io.rong.models.Result;
- import io.rong.models.response.ResponseResult;
- import io.rong.models.response.TokenResult;
- import io.rong.models.user.UserModel;
- import io.swagger.annotations.ApiOperation;
- import org.apache.commons.collections.CollectionUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.PostMapping;
- import org.springframework.web.bind.annotation.RequestBody;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.RestController;
- import javax.servlet.http.HttpServletRequest;
- import java.util.Arrays;
- import java.util.Date;
- import java.util.List;
- import java.util.Objects;
- import java.util.Optional;
- import static com.ym.mec.common.controller.BaseController.succeed;
- @RestController
- @RequestMapping("/user")
- public class UserController {
- private static final Logger log = LoggerFactory.getLogger(UserController.class);
- @Autowired
- private UserService userService;
- @Autowired
- private ImLiveBroadcastRoomService imLiveBroadcastRoomService;
- @Autowired
- private LiveRoomService liveRoomService;
- @Autowired
- private LivePluginContext livePluginContext;
- @Autowired
- private RoomService roomService;
- @Autowired
- private ImGroupCoreService imGroupCoreService;
- @Autowired
- private ImPluginContext imPluginContext;
- @Autowired
- private TeacherDao teacherDao;
- @Autowired
- private SysUserService sysUserService;
- @RequestMapping(value = "/register", method = RequestMethod.POST)
- public Object register(@RequestParam(required = false, defaultValue = "") String clientType,
- @RequestBody UserModel userModel) throws Exception {
- TokenResult tokenResult = new TokenResult(0, "", "", "");
- // 默认使用腾讯云IM
- if (TencentCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())
- && StringUtils.isNotBlank(clientType)) {
- // 用户对象
- BasicUserInfo userInfo = teacherDao.getBasicUserInfo(Integer.parseInt(userModel.getId()));
- if (Objects.nonNull(userInfo)) {
- String username = userInfo.getUsername();
- List<String> userTypes = Lists.newArrayList(userInfo.getUserType().split(","));
- if (userTypes.size() > 1 || userTypes.contains(ClientEnum.TEACHER.getCode())) {
- username = Optional.ofNullable(userInfo.getRealName()).filter(StringUtils::isNotBlank).orElse(username);
- }
- ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(userModel.getId(), clientType, username,
- sysUserService.getImAvatar(teacherDao.getUser(userInfo.getUserId().intValue())));
- // 用户注册接入Token
- tokenResult.setToken(register.getImToken());
- // 用户注册接入Id
- tokenResult.setUserId(register.getImUserId());
- SysUser sysUser = new SysUser();
- sysUser.setId(Integer.parseInt(userModel.getId()));
- // 更新用户imToken值
- sysUser.setImToken(register.getImToken());
- sysUser.setUpdateTime(new Date());
- sysUserService.updateSysUser(sysUser);
- }
- } else {
- // 融云
- tokenResult = userService.register(userModel);
- }
- return tokenResult;
- }
- @ApiOperation("IM用户Token信息")
- @RequestMapping(value = "/userImTokenInfo", method = RequestMethod.POST)
- public ImUserModel.ImUserResult userImTokenInfo(@RequestBody ImUserModel userModel) {
- ImUserModel.ImUserResult tokenResult = new ImUserModel.ImUserResult();
- // 用户对象
- BasicUserInfo userInfo = teacherDao.getBasicUserInfo(Integer.parseInt(userModel.getId()));
- if (Objects.nonNull(userInfo)) {
- String username = userInfo.getUsername();
- List<String> userTypes = Lists.newArrayList(userInfo.getUserType().split(","));
- if (userTypes.size() > 1 || userTypes.contains(ClientEnum.TEACHER.getCode())) {
- username = Optional.ofNullable(userInfo.getRealName()).filter(StringUtils::isNotBlank).orElse(username);
- }
- try {
- ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(userModel.getId(), userModel.getClientType(),
- username, sysUserService.getImAvatar(teacherDao.getUser(userInfo.getUserId().intValue())));
- // 用户注册接入Token
- tokenResult.setImToken(register.getImToken());
- // 用户注册接入Id
- tokenResult.setImUserId(register.getImUserId());
- } catch (Exception e) {
- log.error("注册IM用户Token失败", e);
- }
- }
- return tokenResult;
- }
- @RequestMapping(value = "/update", method = RequestMethod.POST)
- public Object update(@RequestBody UserModel userModel) throws Exception {
- Result result = new ResponseResult(0, "");
- // 默认使用腾讯云IM
- if (TencentCloudImPlugin.PLUGIN_NAME.equals(imPluginContext.defaultService())) {
- // 腾讯云IM
- BasicUserInfo userInfo = teacherDao.getBasicUserInfo(Integer.parseInt(userModel.getId()));
- if (Objects.nonNull(userInfo)) {
- String username = userInfo.getUsername();
- List<String> userTypes = Lists.newArrayList(userInfo.getUserType().split(","));
- if (userTypes.size() > 1 || userTypes.contains(ClientEnum.TEACHER.getCode())) {
- username = Optional.ofNullable(userInfo.getRealName()).filter(StringUtils::isNotBlank).orElse(username);
- }
- try {
- ImGroupWrapper.ImUserInfo register = imGroupCoreService.register(userModel.getId(), "",
- username, sysUserService.getImAvatar(teacherDao.getUser(userInfo.getUserId().intValue())));
- log.info("update IM_USER register: {}", JSONObject.toJSONString(register));
- } catch (Exception e) {
- log.error("更新注册IM用户信息", e);
- }
- }
- } else {
- // 融云IM
- result = userService.update(userModel);
- log.info("update IM_USER result: {}", JSONObject.toJSONString(result));
- }
- return result;
- }
- /**
- * 监听融云用户状态变更
- *
- * @param userState List<ImUserState>
- */
- @PostMapping(value = "/statusImUser")
- public BaseResponse statusImUser(@RequestBody List<ImUserState> userState) {
- log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState));
- imLiveBroadcastRoomService.opsRoom(userState);
- return new BaseResponse<>();
- }
- /**
- * 监听融云用户状态变更
- *
- * @param userState List<ImUserState>
- */
- @PostMapping(value = "/update/statusImUser")
- public Object updateStatusImUser(@RequestBody List<ImUserState> userState) {
- log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(userState));
- imLiveBroadcastRoomService.opsRoom(userState);
- return succeed();
- }
- @PostMapping(value = "/syncLikeCount")
- public Object syncLikeCount(String roomUid) {
- log.info("statusImUser >>>>> : {}", JSONObject.toJSONString(roomUid));
- imLiveBroadcastRoomService.syncLikeCount(roomUid);
- return succeed();
- }
- @ApiOperation("腾讯im 回调接口")
- @PostMapping(value = "/tencentImCallback")
- public TencentImCallbackResult tencentImCallback(@RequestBody String body, HttpServletRequest request) {
- log.info("tencentImCallback body:{}", body);
- LivePluginService pluginService = livePluginContext.getPluginService(TencentCloudLivePlugin.PLUGIN_NAME);
- String appKey = pluginService.getLiveRoomConfig().getAppKey();
- log.info("tencentImCallback request param:{}", JSON.toJSONString(request.getParameterMap()));
- List<String> sdkList = Arrays.asList(request.getParameterValues("SdkAppid"));
- if (sdkList == null || sdkList.size() == 0) {
- log.error("tencentImCallback sdkAppid is null");
- return new TencentImCallbackResult();
- }
- if (!sdkList.contains(appKey)) {
- log.error("tencentImCallback sdkAppid is not match");
- return new TencentImCallbackResult();
- }
- String clientIP = request.getParameter("ClientIP");
- String optPlatform = request.getParameter("OptPlatform");
- if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKONMEMBERSTATECHANGE.getCommand())) {
- // 直播群成员在线状态回调
- TencentData.CallbackOnMemberStateChange callbackOnMemberStateChange = TencentData.CallbackOnMemberStateChange.toObject(
- body);
- // 检查imUserId 是否是当前项目的
- for (TencentData.MemberListDTO memberListDTO : callbackOnMemberStateChange.getMemberList()) {
- if (!imGroupCoreService.checkImUserId(memberListDTO.getMemberAccount())) {
- log.info("tencentImCallback imUserId is not match, imUserId={}", memberListDTO.getMemberAccount());
- return new TencentImCallbackResult();
- }
- }
- log.debug("callbackOnMemberStateChange: {}", callbackOnMemberStateChange);
- callbackOnMemberStateChange.setClientIP(clientIP);
- callbackOnMemberStateChange.setOptPlatform(optPlatform);
- if (callbackOnMemberStateChange.getGroupId().startsWith("LIVE")) {
- // 直播间成员状态变更
- imLiveBroadcastRoomService.callbackOnMemberStateChange(callbackOnMemberStateChange);
- // 直播课学生签退
- String[] values = callbackOnMemberStateChange.getGroupId().split("-");
- String roomId = values.length > 2 ? values[1] : "";
- // 直播课学生签退、签退
- if ((roomId.startsWith("S") || roomId.startsWith("I"))
- && CollectionUtils.isNotEmpty(callbackOnMemberStateChange.getMemberList())) {
- // 学生编号
- String userId = callbackOnMemberStateChange.getMemberList().get(0).getMemberAccount();
- String imUserId = imGroupCoreService.analysisImUserId(userId);
- String eventType = callbackOnMemberStateChange.getEventType();
- // 学生离线消息通知
- if ("Offline".equals(eventType)) {
- try {
- roomService.leaveRoomSuccess(roomId, imUserId, null);
- } catch (Exception e) {
- log.error("tencentImCallback leaveRoomSuccess error, roomId={}, imUserId={}", roomId, imUserId, e);
- }
- }
- // 学生在线消息通知
- if ("Online".equals(eventType)) {
- try {
- roomService.joinRoomSuccess(roomId, imUserId, null);
- } catch (Exception e) {
- log.error("tencentImCallback joinRoomSuccess error, roomId={}, imUserId={}", roomId, imUserId, e);
- }
- }
- }
- }
- } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERMEMBEREXIT.getCommand())) {
- // 群成员离开之后回调
- TencentData.CallbackAfterMemberExit callbackAfterMemberExit = TencentData.CallbackAfterMemberExit.toObject(
- body);
- // 检查imUserId 是否是当前项目的
- for (TencentData.MemberListDTO memberListDTO : callbackAfterMemberExit.getExitMemberList()) {
- if (!imGroupCoreService.checkImUserId(memberListDTO.getMemberAccount())) {
- log.info("tencentImCallback imUserId is not match, imUserId={}", memberListDTO.getMemberAccount());
- return new TencentImCallbackResult();
- }
- }
- log.debug("callbackAfterMemberExit: {}", callbackAfterMemberExit);
- callbackAfterMemberExit.setClientIP(clientIP);
- callbackAfterMemberExit.setOptPlatform(optPlatform);
- if (callbackAfterMemberExit.getGroupId().startsWith("LIVE")) {
- // 直播间成员状态变更
- imLiveBroadcastRoomService.callbackAfterMemberExit(callbackAfterMemberExit);
- // 直播课学生签退
- String[] values = callbackAfterMemberExit.getGroupId().split("-");
- String roomId = values.length > 2 ? values[1] : "";
- // 直播课学生签退、签退
- if ((roomId.startsWith("S") || roomId.startsWith("I"))
- && CollectionUtils.isNotEmpty(callbackAfterMemberExit.getExitMemberList())) {
- // 学生编号
- String userId = callbackAfterMemberExit.getExitMemberList().get(0).getMemberAccount();
- String imUserId = imGroupCoreService.analysisImUserId(userId);
- try {
- roomService.leaveRoomSuccess(roomId, imUserId, null);
- } catch (Exception e) {
- log.error("tencentImCallback leaveRoomSuccess error, roomId={}, imUserId={}", roomId, imUserId, e);
- }
- }
- }
- } else if(request.getParameter("CallbackCommand").equals(ETencentImCallbackCommand.GROUP_CALLBACKAFTERNEWMEMBERJOIN.getCommand())) {
- // 新成员入群之后回调
- TencentData.CallbackAfterNewMemberJoin callbackAfterNewMemberJoin = TencentData.CallbackAfterNewMemberJoin.toObject(
- body);
- // 检查imUserId 是否是当前项目的
- for (TencentData.MemberListDTO memberListDTO : callbackAfterNewMemberJoin.getNewMemberList()) {
- if (!imGroupCoreService.checkImUserId(memberListDTO.getMemberAccount())) {
- log.info("tencentImCallback imUserId is not match, imUserId={}", memberListDTO.getMemberAccount());
- return new TencentImCallbackResult();
- }
- }
- log.debug("CallbackAfterNewMemberJoin: {}", callbackAfterNewMemberJoin);
- callbackAfterNewMemberJoin.setClientIP(clientIP);
- callbackAfterNewMemberJoin.setOptPlatform(optPlatform);
- if (callbackAfterNewMemberJoin.getGroupId().startsWith("LIVE")) {
- // 直播间成员状态变更
- imLiveBroadcastRoomService.callbackAfterNewMemberJoin(callbackAfterNewMemberJoin);
- // 直播课学生签到
- String[] values = callbackAfterNewMemberJoin.getGroupId().split("-");
- String roomId = values.length > 2 ? values[1] : "";
- // 直播课学生签退、签退
- if ((roomId.startsWith("S") || roomId.startsWith("I"))
- && CollectionUtils.isNotEmpty(callbackAfterNewMemberJoin.getNewMemberList())) {
- // 学生编号
- String userId = callbackAfterNewMemberJoin.getNewMemberList().get(0).getMemberAccount();
- String imUserId = imGroupCoreService.analysisImUserId(userId);
- try {
- roomService.joinRoomSuccess(roomId, imUserId, null);
- } catch (Exception e) {
- log.error("tencentImCallback joinRoomSuccess error, roomId={}, imUserId={}", roomId, imUserId, e);
- }
- }
- }
- }
- return new TencentImCallbackResult();
- }
- @ApiOperation("腾讯云直播-推流 回调接口")
- @PostMapping(value = "/tencentStreamEventCallback")
- public TencentData.StreamEventCallbackResult tencentStreamEventCallback(@RequestBody String body) {
- log.info("tencentStreamEventCallback body:{}", body);
- TencentData.CallbackStreamStateEvent event = TencentData.CallbackStreamStateEvent.from(body);
- boolean b = checkStream(event.getStreamId());
- if (!b) {
- return TencentData.StreamEventCallbackResult.builder().code(0).build();
- }
- // 直播间推流事件
- if (event.getStreamId().startsWith("LIVE")) {
- ImUserState imUserState = new ImUserState();
- imUserState.setUserid(getSpeakerId(event.getStreamId()).toString());
- // 断流事件通知
- if (event.getEventType() == 0) {
- Integer speakerId = getSpeakerId(event.getStreamId());
- if (speakerId > 0) {
- // 更新推流时长
- if (StringUtils.isNotBlank(event.getPushDuration()) && event.getPushDuration().matches("\\d+")) {
- // 更新直播推流时长
- imLiveBroadcastRoomService.updateLiveRoomPushStreamTime(event);
- }
- imUserState.setStatus("3");
- // 自动关闭录制
- imLiveBroadcastRoomService.closeLive(getRoomUid(event.getStreamId()), speakerId, event.getSequence());
- // 同步点赞数
- imLiveBroadcastRoomService.syncLikeCount(getRoomUid(event.getStreamId()));
- }
- }
- // 推流事件通知
- if (event.getEventType() == 1) {
- Integer speakerId = getSpeakerId(event.getStreamId());
- if (speakerId > 0) {
- // 自动开启录制
- imLiveBroadcastRoomService.startLive(getRoomUid(event.getStreamId()), getSpeakerId(event.getStreamId()), null,event.getSequence());
- imUserState.setStatus("0");
- }
- }
- //imLiveBroadcastRoomService.opsRoom(Lists.newArrayList(imUserState));
- }
- return TencentData.StreamEventCallbackResult.builder().code(0).build();
- }
- private boolean checkStream(String streamId) {
- return imGroupCoreService.checkImUserId(streamId.split("_",2)[1]);
- }
- private Integer getSpeakerId(String streamId) {
- return Integer.parseInt(imGroupCoreService.analysisImUserId(streamId.split("_",2)[1]));
- }
- private String getRoomUid(String streamId) {
- return streamId.split("_")[0];
- }
- @ApiOperation("腾讯云直播-录制 回调接口")
- @PostMapping(value = "/tencentStreamRecordCallback")
- public TencentData.StreamEventCallbackResult tencentStreamRecordCallback(@RequestBody String body) {
- log.info("tencentStreamRecordCallback body:{}", body);
- TencentData.CallbackSteamRecordEvent event = TencentData.CallbackSteamRecordEvent.from(body);
- boolean b = checkStream(event.getStreamId());
- if (!b) {
- return TencentData.StreamEventCallbackResult.builder().code(0).build();
- }
- // 直播录制事件通知
- if (event.getStreamId().startsWith("LIVE")) {
- log.info("taskId={}, url={}", event.getTaskId(), event.getVideoUrl());
- // 生成直播录制信息
- liveRoomService.createLiveRoomVideoRecord(event);
- }
- return TencentData.StreamEventCallbackResult.builder().code(0).build();
- }
- @ApiOperation("腾讯云直播-推流异常 回调接口")
- @PostMapping(value = "/tencentStreamExceptionCallback")
- public TencentData.StreamEventCallbackResult tencentStreamExceptionCallback(@RequestBody String body) {
- log.info("tencentStreamExceptionCallback body:{}", body);
- return TencentData.StreamEventCallbackResult.builder().code(0).build();
- }
- }
|