From c93ac73e802cbf082559e62cb803bdb78c3d79eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=BF=9C=E6=96=B9=E5=A4=95=E9=98=B3?= Date: Tue, 30 Aug 2022 11:50:26 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9C=8D=E5=8A=A1=E7=AB=AFdemo=E6=96=B0?= =?UTF-8?q?=E5=A2=9Ewebrtc=E4=BF=A1=E4=BB=A4=E6=8E=A5=E5=8F=A3=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cim-boot-server/README.txt | 2 + cim-boot-server/pom.xml | 5 + cim-boot-server/run.sh | 2 +- .../farsunset/cim/annotation/AccessToken.java | 35 ++++ .../cim/annotation/CreateAction.java | 4 + .../com/farsunset/cim/annotation/UID.java | 35 ++++ .../component/redis/TokenRedisTemplate.java | 60 ++++++ .../com/farsunset/cim/config/MvcConfig.java | 76 +++++++ .../farsunset/cim/config/SwaggerConfig.java | 33 ++- .../cim/constants/MessageAction.java | 165 +++++++++++++++ .../mvc/controller/api/UserController.java | 76 +++++++ .../mvc/controller/api/WebrtcController.java | 189 ++++++++++++++++++ .../cim/mvc/interceptor/TokenInterceptor.java | 68 +++++++ .../cim/mvc/request/WebrtcRequest.java | 58 ++++++ .../mvc/resolver/TokenArgumentResolver.java | 46 +++++ .../cim/mvc/resolver/UidArgumentResolver.java | 45 +++++ .../cim/mvc/response/ResponseEntity.java | 109 ++++++++++ .../cim/service/AccessTokenService.java | 32 +++ .../service/impl/AccessTokenServiceImpl.java | 62 ++++++ .../src/main/resources/application.properties | 6 +- 20 files changed, 1101 insertions(+), 7 deletions(-) create mode 100644 cim-boot-server/README.txt create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/annotation/AccessToken.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/annotation/CreateAction.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/annotation/UID.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/component/redis/TokenRedisTemplate.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/config/MvcConfig.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/constants/MessageAction.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/UserController.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/WebrtcController.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/interceptor/TokenInterceptor.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/request/WebrtcRequest.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/TokenArgumentResolver.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/UidArgumentResolver.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/mvc/response/ResponseEntity.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/service/AccessTokenService.java create mode 100644 cim-boot-server/src/main/java/com/farsunset/cim/service/impl/AccessTokenServiceImpl.java diff --git a/cim-boot-server/README.txt b/cim-boot-server/README.txt new file mode 100644 index 0000000..aca2670 --- /dev/null +++ b/cim-boot-server/README.txt @@ -0,0 +1,2 @@ +如果你不想搭建服务端也可以使用,公共的服务器做测试喔 +具体信息参见:https://www.yuque.com/yuanfangxiyang/ma4ytb/vvy3iz#yC5Vq diff --git a/cim-boot-server/pom.xml b/cim-boot-server/pom.xml index 591572b..8be0608 100644 --- a/cim-boot-server/pom.xml +++ b/cim-boot-server/pom.xml @@ -48,6 +48,11 @@ spring-boot-starter-data-jpa + + org.springframework.boot + spring-boot-starter-validation + + org.springframework.boot spring-boot-configuration-processor diff --git a/cim-boot-server/run.sh b/cim-boot-server/run.sh index 409113e..d95476e 100755 --- a/cim-boot-server/run.sh +++ b/cim-boot-server/run.sh @@ -1,3 +1,3 @@ #! /bin/bash -java -Dcom.sun.akuma.Daemon=daemonized -Dspring.profiles.active=pro -jar ./cim-boot-server-4.2.0.jar & \ No newline at end of file +java -Dcom.sun.akuma.Daemon=daemonized -Dspring.profiles.active=dev -Dserver.port=9090 -jar ./cim-boot-server-4.2.0.jar & \ No newline at end of file diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/annotation/AccessToken.java b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/AccessToken.java new file mode 100644 index 0000000..5fd208a --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/AccessToken.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 用户标注通过 token查到的用户账号,注入到Controller参数里面 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AccessToken { +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/annotation/CreateAction.java b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/CreateAction.java new file mode 100644 index 0000000..b76a1f1 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/CreateAction.java @@ -0,0 +1,4 @@ +package com.farsunset.cim.annotation; + +public @interface CreateAction { +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/annotation/UID.java b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/UID.java new file mode 100644 index 0000000..046cb4f --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/annotation/UID.java @@ -0,0 +1,35 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 用户标注通过 token查到的用户账号,注入到Controller参数里面 + */ +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface UID { +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/component/redis/TokenRedisTemplate.java b/cim-boot-server/src/main/java/com/farsunset/cim/component/redis/TokenRedisTemplate.java new file mode 100644 index 0000000..6fee49b --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/component/redis/TokenRedisTemplate.java @@ -0,0 +1,60 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.component.redis; + +import org.springframework.data.redis.connection.RedisConnectionFactory; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; + +@Component +public class TokenRedisTemplate extends StringRedisTemplate { + + private static final String TOKEN_CACHE_PREFIX = "TOKEN_%s"; + + + public TokenRedisTemplate(RedisConnectionFactory connectionFactory) { + super(connectionFactory); + } + + public void save(String token, String uid) { + + String key = String.format(TOKEN_CACHE_PREFIX,token); + + super.boundValueOps(key).set(uid); + } + + public String get(String token) { + + String key = String.format(TOKEN_CACHE_PREFIX,token); + + return super.boundValueOps(key).get(); + + } + + public void remove(String token) { + + String key = String.format(TOKEN_CACHE_PREFIX,token); + + super.delete(key); + } + +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/config/MvcConfig.java b/cim-boot-server/src/main/java/com/farsunset/cim/config/MvcConfig.java new file mode 100644 index 0000000..a4d7d57 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/config/MvcConfig.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.config; + +import com.farsunset.cim.mvc.resolver.TokenArgumentResolver; +import com.farsunset.cim.mvc.resolver.UidArgumentResolver; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.UrlBasedCorsConfigurationSource; +import org.springframework.web.filter.CorsFilter; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +import javax.annotation.Resource; +import java.util.List; + +@Configuration +public class MvcConfig implements WebMvcConfigurer{ + + @Resource + private HandlerInterceptor tokenInterceptor; + + + @Override + public void addInterceptors(InterceptorRegistry registry) { + + registry.addInterceptor(tokenInterceptor) + .addPathPatterns("/webrtc/**"); + + } + + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(new UidArgumentResolver()); + argumentResolvers.add(new TokenArgumentResolver()); + + } + + @Bean + public CorsFilter corsFilter() { + + UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); + CorsConfiguration configuration = new CorsConfiguration(); + configuration.addAllowedOriginPattern("*"); + configuration.addAllowedHeader("*"); + configuration.addAllowedMethod("*"); + configuration.setAllowCredentials(true); + source.registerCorsConfiguration("/**", configuration); + + return new CorsFilter(source); + } + +} \ No newline at end of file diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/config/SwaggerConfig.java b/cim-boot-server/src/main/java/com/farsunset/cim/config/SwaggerConfig.java index ef5dbd4..405f917 100644 --- a/cim-boot-server/src/main/java/com/farsunset/cim/config/SwaggerConfig.java +++ b/cim-boot-server/src/main/java/com/farsunset/cim/config/SwaggerConfig.java @@ -26,10 +26,14 @@ import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.oas.annotations.EnableOpenApi; -import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.*; import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spi.service.contexts.SecurityContext; import springfox.documentation.spring.web.plugins.Docket; +import java.util.ArrayList; +import java.util.List; + @EnableOpenApi @Configuration public class SwaggerConfig { @@ -38,10 +42,12 @@ public class SwaggerConfig { public Docket userApiDocket(ApiInfo apiInfo) { return new Docket(DocumentationType.OAS_30) .apiInfo(apiInfo) - .groupName("APP接口") + .groupName("客户端接口") .select() .apis(RequestHandlerSelectors.basePackage("com.farsunset.cim.mvc.controller.api")) - .build(); + .build() + .securitySchemes(securitySchemes()) + .securityContexts(securityContexts()); } @Bean @@ -49,8 +55,27 @@ public class SwaggerConfig { return new ApiInfoBuilder() .title("CIM Push Service APIs.") .description("CIM客户端接口文档") - .version("2.0") + .version("3.0") .build(); } + private List securitySchemes() { + List schemeList = new ArrayList<>(); + schemeList.add(new ApiKey("access-token", "access-token", "header")); + return schemeList; + } + + private List securityContexts() { + List securityContextList = new ArrayList<>(); + List securityReferenceList = new ArrayList<>(); + securityReferenceList.add(new SecurityReference("access-token", new AuthorizationScope[]{new AuthorizationScope("global", "accessAnything")})); + securityContextList.add(SecurityContext + .builder() + .securityReferences(securityReferenceList) + .operationSelector(operationContext -> true) + .build() + ); + return securityContextList; + } + } diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/constants/MessageAction.java b/cim-boot-server/src/main/java/com/farsunset/cim/constants/MessageAction.java new file mode 100644 index 0000000..c3d2546 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/constants/MessageAction.java @@ -0,0 +1,165 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.constants; + +public interface MessageAction { + + /* + * 系统定制消息---语音通话请求 + */ + String ACTION_900 = "900"; + + /* + * 系统定制消息---视频通话请求 + */ + String ACTION_901 = "901"; + + /* + * 系统定制消息---通话接受 + */ + String ACTION_902 = "902"; + + /* + * 系统定制消息---通话拒绝 + */ + String ACTION_903 = "903"; + + /* + * 系统定制消息---对方正忙 + */ + String ACTION_904 = "904"; + + /* + * 系统定制消息---对方挂断 + */ + String ACTION_905 = "905"; + + /* + * 系统定制消息---取消呼叫 + */ + String ACTION_906 = "906"; + + /* + * 系统定制消息---同步ICE SPD + */ + String ACTION_907 = "907"; + + /* + * 系统定制消息---同步Offer + */ + String ACTION_908 = "908"; + + /* + * 系统定制消息---同步Answer + */ + String ACTION_909 = "909"; + + /* + * 系统定制消息---多人语音通话请求 + */ + String ACTION_910 = "910"; + + /* + * 系统定制消息---多人视频通话请求 + */ + String ACTION_911 = "911"; + + /* + *系统定制消息---多人通话-同意 + */ + String ACTION_912 = "912"; + + /* + *系统定制消息---多人通话-拒绝 + */ + String ACTION_913 = "913"; + + /* + *系统定制消息---多人通话-忙线 + */ + String ACTION_914 = "914"; + + /* + *系统定制消息---多人通话-开麦开关 + */ + String ACTION_915 = "915"; + + /* + *系统定制消息---多人通话-摄像头开关 + */ + String ACTION_916 = "916"; + + /* + *系统定制消息---多人通话-加人 + */ + String ACTION_917 = "917"; + + /* + *系统定制消息---多人通话-退出 + */ + String ACTION_918 = "918"; + + /* + *系统定制消息---多人通话-取消呼叫 + */ + String ACTION_919 = "919"; + + /* + * 系统定制消息---多人通话-同步Offer + */ + String ACTION_920 = "920"; + + /* + * 系统定制消息---多人通话-同步Answer + */ + String ACTION_921 = "921"; + + /* + * 系统定制消息---多人通话-同步ICE + */ + String ACTION_922 = "922"; + + /* + *系统定制消息---多人通话-未响应 + */ + String ACTION_923 = "923"; + + /* + *系统定制消息---多人通话-结束会议 + */ + String ACTION_924 = "924"; + + /* + *系统定制消息---多人通话-全员静音 + */ + String ACTION_925 = "925"; + + /* + *系统定制消息---多人通话-取消全员静音 + */ + String ACTION_926 = "926"; + + /* + *系统定制消息---多人通话-有人再次被呼叫 + */ + String ACTION_927 = "927"; +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/UserController.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/UserController.java new file mode 100644 index 0000000..f9f7807 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/UserController.java @@ -0,0 +1,76 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.controller.api; + + +import com.farsunset.cim.annotation.AccessToken; +import com.farsunset.cim.mvc.response.ResponseEntity; +import com.farsunset.cim.service.AccessTokenService; +import io.swagger.annotations.*; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.HashMap; +import java.util.Map; + +@RestController +@RequestMapping("/user") +@Api(produces = "application/json", tags = "用户登录接口" ) +@Validated +public class UserController { + + @Resource + private AccessTokenService accessTokenService; + + @ApiOperation(httpMethod = "POST", value = "模拟登录") + @ApiImplicitParams({ + @ApiImplicitParam(name = "telephone", value = "手机号码", paramType = "query", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "密码", paramType = "query", dataTypeClass = String.class), + }) + @PostMapping(value = "/login") + public ResponseEntity login(@RequestParam String telephone) { + + + Map body = new HashMap<>(); + body.put("id",Long.parseLong(telephone)); + body.put("name","测试用户"); + body.put("telephone","telephone"); + + ResponseEntity> result = new ResponseEntity<>(); + + result.setData(body); + + result.setToken(accessTokenService.generate(telephone)); + result.setTimestamp(System.currentTimeMillis()); + return result; + } + + + @ApiOperation(httpMethod = "GET", value = "退出登录") + @GetMapping(value = "/logout") + public ResponseEntity logout(@ApiParam(hidden = true) @AccessToken String token) { + accessTokenService.delete(token); + return ResponseEntity.make(); + } + +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/WebrtcController.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/WebrtcController.java new file mode 100644 index 0000000..de63e34 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/controller/api/WebrtcController.java @@ -0,0 +1,189 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.controller.api; + +import com.farsunset.cim.annotation.UID; +import com.farsunset.cim.component.push.DefaultMessagePusher; +import com.farsunset.cim.constants.MessageAction; +import com.farsunset.cim.model.Message; +import com.farsunset.cim.mvc.request.WebrtcRequest; +import com.farsunset.cim.mvc.response.ResponseEntity; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiOperation; +import io.swagger.annotations.ApiParam; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController +@RequestMapping("/webrtc") +@Api(produces = "application/json", tags = "单人通话信令推送接口" ) +public class WebrtcController { + + @Resource + private DefaultMessagePusher defaultMessagePusher; + + @ApiOperation(httpMethod = "POST", value = "发起单人语音通话") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/voice"}) + public ResponseEntity voice(@ApiParam(hidden = true) @UID String uid,@RequestParam String targetId) { + + + Message message = new Message(); + message.setAction(MessageAction.ACTION_900); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + + @ApiOperation(httpMethod = "POST", value = "发起单人视频通话") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/video"}) + public ResponseEntity video(@ApiParam(hidden = true) @UID String uid,@RequestParam String targetId) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_901); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "接受通话") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/accept"}) + public ResponseEntity accept(@ApiParam(hidden = true) @UID String uid,@RequestParam String targetId) { + Message message = new Message(); + message.setAction(MessageAction.ACTION_902); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "拒绝通话") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/reject"}) + public ResponseEntity reject(@ApiParam(hidden = true) @UID String uid,@RequestParam String targetId) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_903); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "反馈正忙") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/busy"}) + public ResponseEntity busy(@ApiParam(hidden = true) @UID String uid, @RequestParam String targetId) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_904); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "挂断通话") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/hangup"}) + public ResponseEntity hangup(@ApiParam(hidden = true) @UID String uid,@RequestParam String targetId) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_905); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "取消呼叫") + @ApiImplicitParam(name = "targetId", value = "对方用户ID", paramType = "query", dataTypeClass = Long.class) + @PostMapping(value = {"/cancel"}) + public ResponseEntity cancel(@ApiParam(hidden = true) @UID String uid, @RequestParam String targetId) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_906); + message.setSender(uid); + message.setReceiver(targetId); + defaultMessagePusher.push(message); + + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "同步IceCandidate") + @PostMapping(value = {"/transmit/ice"}) + public ResponseEntity ice(@ApiParam(hidden = true) @UID String uid, + @RequestBody WebrtcRequest request + ) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_907); + message.setSender(uid); + message.setContent(request.getContent()); + message.setReceiver(request.getUid()); + defaultMessagePusher.push(message); + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "同步offer") + @PostMapping(value = {"/transmit/offer"}) + public ResponseEntity offer(@ApiParam(hidden = true) @UID String uid, + @RequestBody WebrtcRequest request + ) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_908); + message.setSender(uid); + message.setContent(request.getContent()); + message.setReceiver(request.getUid()); + defaultMessagePusher.push(message); + return ResponseEntity.make(); + } + + @ApiOperation(httpMethod = "POST", value = "同步answer") + @PostMapping(value = {"/transmit/answer"}) + public ResponseEntity answer(@ApiParam(hidden = true) @UID String uid, + @RequestBody WebrtcRequest request + ) { + + Message message = new Message(); + message.setAction(MessageAction.ACTION_909); + message.setSender(uid); + message.setContent(request.getContent()); + message.setReceiver(request.getUid()); + defaultMessagePusher.push(message); + return ResponseEntity.make(); + } +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/interceptor/TokenInterceptor.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/interceptor/TokenInterceptor.java new file mode 100644 index 0000000..351027a --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/interceptor/TokenInterceptor.java @@ -0,0 +1,68 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.interceptor; + +import com.farsunset.cim.annotation.AccessToken; +import com.farsunset.cim.annotation.UID; +import com.farsunset.cim.service.AccessTokenService; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Component; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 在此鉴权获得UID + */ +@Component +public class TokenInterceptor implements HandlerInterceptor { + + private static final String HEADER_TOKEN = "access-token"; + + @Resource + private AccessTokenService accessTokenService; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { + + String token = request.getHeader(HEADER_TOKEN); + + String uid = accessTokenService.getUid(token); + + /* + * 直接拒绝无token的接口调用请求或者token没有查询到对应的登录用户 + */ + if (uid == null) { + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + return false; + } + + request.setAttribute(UID.class.getName(), uid); + request.setAttribute(AccessToken.class.getName(), token); + + return true; + + } +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/request/WebrtcRequest.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/request/WebrtcRequest.java new file mode 100644 index 0000000..a52ad5c --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/request/WebrtcRequest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.request; + +import com.farsunset.cim.annotation.CreateAction; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.io.Serializable; + +@ApiModel("单人通话ice、offer、answer同步请求体") +public class WebrtcRequest implements Serializable { + + @NotNull(message = "UID不能为空",groups = CreateAction.class) + @ApiModelProperty("对方UID") + private String uid; + + @NotEmpty(message = "content不能超过2000个字符",groups = CreateAction.class) + @ApiModelProperty("ice信息json、offer或者answer的sdp") + private String content; + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/TokenArgumentResolver.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/TokenArgumentResolver.java new file mode 100644 index 0000000..712098b --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/TokenArgumentResolver.java @@ -0,0 +1,46 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.resolver; + +import com.farsunset.cim.annotation.AccessToken; +import com.farsunset.cim.annotation.UID; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +public class TokenArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(AccessToken.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + return webRequest.getAttribute(AccessToken.class.getName(),RequestAttributes.SCOPE_REQUEST); + } + +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/UidArgumentResolver.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/UidArgumentResolver.java new file mode 100644 index 0000000..62e0ba0 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/resolver/UidArgumentResolver.java @@ -0,0 +1,45 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.resolver; + +import com.farsunset.cim.annotation.UID; +import org.springframework.core.MethodParameter; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.RequestAttributes; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +public class UidArgumentResolver implements HandlerMethodArgumentResolver { + + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.hasParameterAnnotation(UID.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, + NativeWebRequest webRequest, WebDataBinderFactory binderFactory) { + return webRequest.getAttribute(UID.class.getName(),RequestAttributes.SCOPE_REQUEST); + } + +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/mvc/response/ResponseEntity.java b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/response/ResponseEntity.java new file mode 100644 index 0000000..cd3e62c --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/mvc/response/ResponseEntity.java @@ -0,0 +1,109 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.mvc.response; + +import org.springframework.http.HttpStatus; + +public class ResponseEntity { + private int code = HttpStatus.OK.value(); + private String message; + private T data; + private String token; + private Long timestamp; + + public int getCode() { + return code; + } + + public void setCode(int code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } + + public T getData() { + return data; + } + + public void setData(T data) { + this.data = data; + } + + public String getToken() { + return token; + } + + public Long getTimestamp() { + return timestamp; + } + + public void setTimestamp(Long timestamp) { + this.timestamp = timestamp; + } + + public void setToken(String token) { + this.token = token; + } + + public static ResponseEntity make(){ + return new ResponseEntity<>(); + } + + public static ResponseEntity make(int code){ + return make(code,null); + } + + public static ResponseEntity make(int code,String message){ + ResponseEntity result = new ResponseEntity<>(); + result.setCode(code); + result.setMessage(message); + return result; + } + + public static ResponseEntity make(HttpStatus status){ + ResponseEntity result = new ResponseEntity<>(); + result.setCode(status.value()); + result.setMessage(status.getReasonPhrase()); + return result; + } + + public static ResponseEntity make(HttpStatus status,String message){ + ResponseEntity result = new ResponseEntity<>(); + result.setCode(status.value()); + result.setMessage(message); + return result; + } + + + public static ResponseEntity ok(Q data){ + ResponseEntity result = new ResponseEntity<>(); + result.setData(data); + return result; + } + +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/service/AccessTokenService.java b/cim-boot-server/src/main/java/com/farsunset/cim/service/AccessTokenService.java new file mode 100644 index 0000000..44509b4 --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/service/AccessTokenService.java @@ -0,0 +1,32 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.service; + + +public interface AccessTokenService { + + String generate(String uid); + + String getUid(String token); + + void delete(String value); +} diff --git a/cim-boot-server/src/main/java/com/farsunset/cim/service/impl/AccessTokenServiceImpl.java b/cim-boot-server/src/main/java/com/farsunset/cim/service/impl/AccessTokenServiceImpl.java new file mode 100644 index 0000000..6f1c29e --- /dev/null +++ b/cim-boot-server/src/main/java/com/farsunset/cim/service/impl/AccessTokenServiceImpl.java @@ -0,0 +1,62 @@ +/* + * Copyright 2013-2019 Xia Jun(3979434@qq.com). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + *************************************************************************************** + * * + * Website : http://www.farsunset.com * + * * + *************************************************************************************** + */ +package com.farsunset.cim.service.impl; + +import com.farsunset.cim.component.redis.TokenRedisTemplate; +import com.farsunset.cim.service.AccessTokenService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.UUID; + +@Service +public class AccessTokenServiceImpl implements AccessTokenService { + @Resource + private TokenRedisTemplate tokenRedisTemplate; + + @Override + public String getUid(String token) { + if (StringUtils.isBlank(token)){ + return null; + } + return tokenRedisTemplate.get(token); + } + + @Override + public void delete(String token) { + tokenRedisTemplate.delete(token); + } + + /** + * 方便调试,这里生成token为永不过期 + * @param uid + * @return + */ + @Override + public String generate(String uid) { + String newToken = UUID.randomUUID().toString().replace("-",""); + tokenRedisTemplate.save(newToken, uid); + return newToken; + } + +} diff --git a/cim-boot-server/src/main/resources/application.properties b/cim-boot-server/src/main/resources/application.properties index b1a3ef4..9fcfbbb 100644 --- a/cim-boot-server/src/main/resources/application.properties +++ b/cim-boot-server/src/main/resources/application.properties @@ -1,5 +1,7 @@ server.port=8080 +spring.jackson.default-property-inclusion=non_empty + #单台服务器可设置为dev,广播消息走本地消息事件(参见SignalRedisTemplate.java) #多台服务器集群环境设置为prd,广播消息走三方消息队列 spring.profiles.active=dev @@ -9,8 +11,8 @@ spring.profiles.active=dev # JDBC Config # ################################################################## spring.datasource.url = jdbc:mysql://127.0.0.1:3306/cim?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC -spring.datasource.username = root -spring.datasource.password = root +spring.datasource.username = cim +spring.datasource.password = f8HYPmssXL6XmZeK spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver