6.3 实现微服务:匹配系统(下)

master
barney 2 years ago
parent 108ae844f0
commit 1e2149a014
  1. BIN
      backend/lib/javax.annotation.jar
  2. BIN
      backend/lib/javax.ejb.jar
  3. BIN
      backend/lib/javax.jms.jar
  4. BIN
      backend/lib/javax.persistence.jar
  5. BIN
      backend/lib/javax.resource.jar
  6. BIN
      backend/lib/javax.servlet.jar
  7. BIN
      backend/lib/javax.servlet.jsp.jar
  8. BIN
      backend/lib/javax.servlet.jsp.jstl.jar
  9. BIN
      backend/lib/javax.transaction.jar
  10. 52
      backend/src/main/java/com/kob/backend/controller/pk/BotInfoController.java
  11. 18
      backend/src/main/java/com/kob/backend/controller/pk/IndexController.java
  12. 0
      backendCloud/.gitignore
  13. 0
      backendCloud/.mvn/wrapper/maven-wrapper.jar
  14. 2
      backendCloud/.mvn/wrapper/maven-wrapper.properties
  15. 45
      backendCloud/backend/pom.xml
  16. 0
      backendCloud/backend/src/main/java/com/kob/backend/BackendApplication.java
  17. 0
      backendCloud/backend/src/main/java/com/kob/backend/config/CorsConfig.java
  18. 13
      backendCloud/backend/src/main/java/com/kob/backend/config/RestTemplateConfig.java
  19. 1
      backendCloud/backend/src/main/java/com/kob/backend/config/SecurityConfig.java
  20. 0
      backendCloud/backend/src/main/java/com/kob/backend/config/WebSocketConfig.java
  21. 0
      backendCloud/backend/src/main/java/com/kob/backend/config/filter/JwtAuthenticationTokenFilter.java
  22. 106
      backendCloud/backend/src/main/java/com/kob/backend/consumer/WebSocketServer.java
  23. 0
      backendCloud/backend/src/main/java/com/kob/backend/consumer/utils/Cell.java
  24. 6
      backendCloud/backend/src/main/java/com/kob/backend/consumer/utils/Game.java
  25. 0
      backendCloud/backend/src/main/java/com/kob/backend/consumer/utils/JwtAuthentication.java
  26. 0
      backendCloud/backend/src/main/java/com/kob/backend/consumer/utils/Player.java
  27. 28
      backendCloud/backend/src/main/java/com/kob/backend/controller/pk/StartGameController.java
  28. 1
      backendCloud/backend/src/main/java/com/kob/backend/controller/pojo/Bot.java
  29. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/pojo/Record.java
  30. 1
      backendCloud/backend/src/main/java/com/kob/backend/controller/pojo/User.java
  31. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/UserDetailsServiceImpl.java
  32. 15
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/pk/StartGameServiceImpl.java
  33. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/account/InfoServiceImpl.java
  34. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/account/LoginServiceImpl.java
  35. 2
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/account/RegisterServiceImpl.java
  36. 2
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/bot/AddServiceImpl.java
  37. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/bot/GetListServiceImpl.java
  38. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/bot/RemoveServiceImpl.java
  39. 2
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/user/bot/UpdateServiceImpl.java
  40. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/impl/utils/UserDetailsImpl.java
  41. 8
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/pk/StartGameService.java
  42. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/account/InfoService.java
  43. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/account/LoginService.java
  44. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/account/RegisterService.java
  45. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/bot/AddService.java
  46. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/bot/GetListService.java
  47. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/bot/RemoveService.java
  48. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/service/user/bot/UpdateService.java
  49. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/account/InfoServiceController.java
  50. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/account/LoginController.java
  51. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/account/RegisterController.java
  52. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/bot/AddController.java
  53. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/bot/GetListController.java
  54. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/bot/RemoveController.java
  55. 0
      backendCloud/backend/src/main/java/com/kob/backend/controller/user/bot/UpdateController.java
  56. 0
      backendCloud/backend/src/main/java/com/kob/backend/mapper/BotMapper.java
  57. 0
      backendCloud/backend/src/main/java/com/kob/backend/mapper/RecordMapper.java
  58. 0
      backendCloud/backend/src/main/java/com/kob/backend/mapper/UserMapper.java
  59. 0
      backendCloud/backend/src/main/java/com/kob/backend/utils/JwtUtil.java
  60. 0
      backendCloud/backend/src/main/resources/application.properties
  61. 0
      backendCloud/backend/src/main/resources/static/image/kob.png
  62. 0
      backendCloud/backend/src/main/resources/static/image/test1.jpg
  63. 0
      backendCloud/backend/src/main/resources/templates/pk/index.html
  64. 0
      backendCloud/backend/src/test/java/com/kob/backend/BackendApplicationTests.java
  65. 56
      backendCloud/matchingsystem/pom.xml
  66. 14
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/MatchingSystemApplication.java
  67. 13
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/config/RestTemplateConfig.java
  68. 30
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/config/SecurityConfig.java
  69. 30
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/controller/MatchingController.java
  70. 6
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/service/MatchingService.java
  71. 25
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/service/impl/MatchingServiceImpl.java
  72. 121
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/service/impl/utils/MatchingPool.java
  73. 14
      backendCloud/matchingsystem/src/main/java/com/kob/matchingsystem/service/impl/utils/Player.java
  74. 1
      backendCloud/matchingsystem/src/main/resources/application.properties
  75. 0
      backendCloud/mvnw
  76. 0
      backendCloud/mvnw.cmd
  77. 34
      backendCloud/pom.xml
  78. 12
      web/src/components/MatchGround.vue
  79. 2
      web/src/components/ResultBoard.vue
  80. 2
      web/src/views/pk/PkIndexView.vue

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

@ -1,52 +0,0 @@
package com.kob.backend.controller.pk;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
/**
* @author zfp
*/
@RestController
@RequestMapping("/pk/")
public class BotInfoController {
@RequestMapping("getInfo/")
public List<Map<String,String>> getInfo(){
List<Map<String,String>> li = new LinkedList<>();
Map<String,String> bot1 = new HashMap<>(3);
bot1.put("name","John");
bot1.put("age","14");
bot1.put("sex","male");
Map<String,String> bot2 = new HashMap<>(3);
bot2.put("name","smith");
bot2.put("age","18");
bot2.put("sex","female");
li.add(bot1);
li.add(bot2);
return li;
}
@RequestMapping("getInfo1/")
public List<String> getInfo1(){
List<String> li = new LinkedList<>();
li.add("apple");
li.add("banana");
li.add("cat");
return li;
}
@RequestMapping("getInfo2/")
public Map<String,String> getInfo2(){
Map<String,String> map = new HashMap<>();
map.put("name","acwing");
map.put("rating","100");
return map;
}
}

@ -1,18 +0,0 @@
package com.kob.backend.controller.pk;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author zfp
*/
@Controller
public class IndexController {
@RequestMapping("/")
public String getIndex(){
return "pk/index.html";
}
}

@ -1,2 +1,2 @@
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.5/apache-maven-3.8.5-bin.zip
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar

@ -1,21 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
<artifactId>backendCloud</artifactId>
<groupId>com.kob</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<groupId>com.kob</groupId>
<modelVersion>4.0.0</modelVersion>
<groupId>com.kob.backend</groupId>
<artifactId>backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>backend</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
@ -86,13 +88,6 @@
<version>2.0.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
@ -105,14 +100,4 @@
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.1</version>
</plugin>
</plugins>
</build>
</project>
</project>

@ -0,0 +1,13 @@
package com.kob.backend.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

@ -44,6 +44,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
.and()
.authorizeRequests()
.antMatchers("/user/account/token/", "/user/account/register/").permitAll()
.antMatchers("/pk/start/game/").hasIpAddress("127.0.0.1")
.antMatchers(HttpMethod.OPTIONS).permitAll()
.anyRequest().authenticated();

@ -8,7 +8,11 @@ import com.kob.backend.mapper.RecordMapper;
import com.kob.backend.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import javax.swing.plaf.PanelUI;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
@ -27,20 +31,22 @@ public class WebSocketServer {
// 保存所有用户对应的请求链接
// 线程安全的一个HashMap
public final static ConcurrentHashMap<Integer,WebSocketServer> users = new ConcurrentHashMap<>();
// 保存当前的匹配池
private final static CopyOnWriteArraySet<User> matchpool = new CopyOnWriteArraySet<>();
// 发起请求链接对应的用户
private User user;
private Session session = null;
private Game game = null;
// 注入userMapper(和之前的有点不一样)
private static UserMapper userMapper;
// 注入RecordMapper
public static RecordMapper recordMapper;
private Game game = null;
// 注入RestTemplate
private static RestTemplate restTemplate; // 可以作用于两个springboot进程间的通信
private static final String addPlayerUrl = "http://127.0.0.1:3001/player/add/";
private static final String removePlayerUrl = "http://127.0.0.1:3001/player/remove/";
@Autowired
public void setUserMapper(UserMapper userMapper) {
@ -52,6 +58,11 @@ public class WebSocketServer {
WebSocketServer.recordMapper = recordMapper;
}
@Autowired
private void setRestTemplate(RestTemplate restTemplate) {
WebSocketServer.restTemplate = restTemplate;
}
@OnOpen
public void onOpen(Session session, @PathParam("token") String token) throws IOException {
// 建立连接
@ -78,65 +89,70 @@ public class WebSocketServer {
System.out.println("Disconnected!");
if (this.user != null) {
users.remove(this.user.getId());
matchpool.remove(this.user);
}
}
public static void startGame(Integer aId, Integer bId) {
User a = userMapper.selectById(aId),b = userMapper.selectById(bId);
private void startMatching() {
System.out.println("start-----matching----");
matchpool.add(this.user);
while (matchpool.size() >= 2) {
Iterator<User> it = matchpool.iterator();
User a = it.next(), b = it.next();
matchpool.remove(a);
matchpool.remove(b);
Game game = new Game(13,14,20,a.getId(),b.getId());
game.createMap();
Game game = new Game(13,14,20,a.getId(),b.getId());
game.createMap();
if (users.get(a.getId()) != null)
users.get(a.getId()).game = game;
users.get(b.getId()).game = game;
game.start(); // 重新开一个新线程
if (users.get(b.getId()) != null)
users.get(b.getId()).game = game;
game.start(); // 重新开一个新线程
// 两名玩家的id,位置以及地图保存在respGame中
JSONObject respGame = new JSONObject();
respGame.put("a_id",game.getPlayerA().getId());
respGame.put("a_sx",game.getPlayerA().getSx());
respGame.put("a_sy",game.getPlayerA().getSy());
respGame.put("b_id",game.getPlayerB().getId());
respGame.put("b_sx",game.getPlayerB().getSx());
respGame.put("b_sy",game.getPlayerB().getSy());
respGame.put("map",game.getG());
// 两名玩家的id,位置以及地图保存在respGame中
JSONObject respGame = new JSONObject();
respGame.put("a_id",game.getPlayerA().getId());
respGame.put("a_sx",game.getPlayerA().getSx());
respGame.put("a_sy",game.getPlayerA().getSy());
respGame.put("b_id",game.getPlayerB().getId());
respGame.put("b_sx",game.getPlayerB().getSx());
respGame.put("b_sy",game.getPlayerB().getSy());
respGame.put("map",game.getG());
JSONObject respA = new JSONObject();
respA.put("event","start-matching");
respA.put("opponent_username",b.getUsername());
respA.put("opponent_photo",b.getPhoto());
respA.put("game",respGame);
JSONObject respA = new JSONObject();
respA.put("event","start-matching");
respA.put("opponent_username",b.getUsername());
respA.put("opponent_photo",b.getPhoto());
respA.put("game",respGame);
if (users.get(a.getId()) != null)
users.get(a.getId()).sendMessage(respA.toJSONString());
JSONObject respB = new JSONObject();
respB.put("event","start-matching");
respB.put("opponent_username",a.getUsername());
respB.put("opponent_photo",a.getPhoto());
respB.put("game",respGame);
JSONObject respB = new JSONObject();
respB.put("event","start-matching");
respB.put("opponent_username",a.getUsername());
respB.put("opponent_photo",a.getPhoto());
respB.put("game",respGame);
if (users.get(b.getId()) != null)
users.get(b.getId()).sendMessage(respB.toJSONString());
}
// System.out.println(respGame);
}
private void startMatching() {
System.out.println("start-----matching----");
MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
// 请求参数
data.add("user_id",this.user.getId().toString());
data.add("rating",this.user.getRating().toString());
// 向后端发送请求,添加一个用户
restTemplate.postForObject(addPlayerUrl,data,String.class);
}
private void stopMatching() {
System.out.println("stop-----matching----");
matchpool.remove(this.user);
// 向后端发送请求,删除一个用户
MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
data.add("user_id",this.user.getId().toString());
restTemplate.postForObject(removePlayerUrl,data,String.class);
}
private void move(int direction) {

@ -172,8 +172,10 @@ public class Game extends Thread {
}
private void sendAllMessage(String message) { // 向两个client传递信息
WebSocketServer.users.get(playerA.getId()).sendMessage(message);
WebSocketServer.users.get(playerB.getId()).sendMessage(message);
if (WebSocketServer.users.get(playerA.getId()) != null)
WebSocketServer.users.get(playerA.getId()).sendMessage(message);
if (WebSocketServer.users.get(playerB.getId()) != null)
WebSocketServer.users.get(playerB.getId()).sendMessage(message);
}

@ -0,0 +1,28 @@
package com.kob.backend.controller.pk;
import com.kob.backend.controller.service.pk.StartGameService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@RestController
public class StartGameController {
@Autowired
private StartGameService startGameService;
@PostMapping("/pk/start/game/")
public String startGame(@RequestParam MultiValueMap<String,String> data) {
Integer aId = Integer.parseInt(Objects.requireNonNull(data.getFirst("a_id")));
Integer bId = Integer.parseInt(Objects.requireNonNull(data.getFirst("b_id")));
return startGameService.startGame(aId,bId);
}
}

@ -24,7 +24,6 @@ public class Bot {
private String title;
private String description;
private String content;
private Integer rating;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "Asia/Shanghai")

@ -25,4 +25,5 @@ public class User {
private String username;
private String password;
private String photo;
private Integer rating;
}

@ -0,0 +1,15 @@
package com.kob.backend.controller.service.impl.pk;
import com.kob.backend.consumer.WebSocketServer;
import com.kob.backend.controller.service.pk.StartGameService;
import org.springframework.stereotype.Service;
@Service
public class StartGameServiceImpl implements StartGameService {
@Override
public String startGame(Integer aId, Integer bId) {
System.out.println("PlayerA id: " + aId + ", PlayerB id:" + bId);
WebSocketServer.startGame(aId,bId);
return "start game success";
}
}

@ -76,7 +76,7 @@ public class RegisterServiceImpl implements RegisterService {
// 将用户密码加密
String encodedPassword = passwordEncoder.encode(password);
String photo = "https://cdn.acwing.com/media/user/profile/photo/41648_lg_8d1ad446b6.jpg";
User user = new User(null,username,encodedPassword,photo);
User user = new User(null,username,encodedPassword,photo,1500);
// 将用户数据存入数据库
userMapper.insert(user);

@ -69,7 +69,7 @@ public class AddServiceImpl implements AddService {
}
Date now = new Date();
Bot bot = new Bot(null, user.getId(), title, description, content, 1500, now, now);
Bot bot = new Bot(null, user.getId(), title, description, content, now, now);
botMapper.insert(bot);
map.put("error_msg", "success");

@ -87,7 +87,7 @@ public class UpdateServiceImpl implements UpdateService {
}
// 如果可以修改该bot
Bot newBot = new Bot(bot.getId(), user.getId(), title,description,content,bot.getRating(),bot.getCreateTime(),new Date());
Bot newBot = new Bot(bot.getId(), user.getId(), title,description,content,bot.getCreateTime(),new Date());
botMapper.updateById(newBot);
map.put("error_msg","success");
return map;

@ -0,0 +1,8 @@
package com.kob.backend.controller.service.pk;
import org.springframework.stereotype.Service;
public interface StartGameService {
String startGame(Integer aId,Integer bId);
}

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>backendCloud</artifactId>
<groupId>com.kob</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.kob.matchingsystem</groupId>
<artifactId>matchingsystem</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2021.0.3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,14 @@
package com.kob.matchingsystem;
import com.kob.matchingsystem.service.impl.MatchingServiceImpl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MatchingSystemApplication {
public static void main(String[] args)
{
MatchingServiceImpl.matchingPool.start(); // 启动匹配线程
SpringApplication.run(MatchingSystemApplication.class,args);
}
}

@ -0,0 +1,13 @@
package com.kob.matchingsystem.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}

@ -0,0 +1,30 @@
package com.kob.matchingsystem.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
/**
* @author zfp
*/
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable()
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
.antMatchers("/player/add/", "/player/remove/").hasIpAddress("127.0.0.1")
.antMatchers(HttpMethod.OPTIONS).permitAll()
.anyRequest().authenticated();
}
}

@ -0,0 +1,30 @@
package com.kob.matchingsystem.controller;
import com.kob.matchingsystem.service.MatchingService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.Objects;
@RestController
public class MatchingController {
@Autowired
private MatchingService matchingService;
@PostMapping("/player/add/")
public String addPlayer(@RequestParam MultiValueMap<String,String> data) {
Integer userId = Integer.parseInt(Objects.requireNonNull(data.getFirst("user_id")));
Integer rating = Integer.parseInt(Objects.requireNonNull(data.getFirst("rating")));
return matchingService.addPlayer(userId,rating);
}
@PostMapping("/player/remove/")
public String removePlayer(@RequestParam MultiValueMap<String,String> data) {
Integer userId = Integer.parseInt(Objects.requireNonNull(data.getFirst("user_id")));
return matchingService.removePlayer(userId);
}
}

@ -0,0 +1,6 @@
package com.kob.matchingsystem.service;
public interface MatchingService {
String addPlayer(Integer userId, Integer rating);
String removePlayer(Integer userId);
}

@ -0,0 +1,25 @@
package com.kob.matchingsystem.service.impl;
import com.kob.matchingsystem.service.MatchingService;
import com.kob.matchingsystem.service.impl.utils.MatchingPool;
import org.springframework.stereotype.Service;
@Service
public class MatchingServiceImpl implements MatchingService {
public static final MatchingPool matchingPool = new MatchingPool();
@Override
public String addPlayer(Integer userId, Integer rating) {
System.out.println("<add user> user id: " + userId + ", rating: " + rating);
matchingPool.addPlayer(userId,rating);
return "add user success";
}
@Override
public String removePlayer(Integer userId) {
System.out.println("<remove user> user id: " + userId);
matchingPool.removePlayer(userId);
return "remove user success";
}
}

@ -0,0 +1,121 @@
package com.kob.matchingsystem.service.impl.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
@Component
public class MatchingPool extends Thread{
public static List<Player> players = new ArrayList<>();
// 加锁
public ReentrantLock lock = new ReentrantLock();
private static RestTemplate restTemplate;
private static final String startGameUrl= "http://127.0.0.1:3000/pk/start/game/";
@Autowired
public void setRestTemplate(RestTemplate restTemplate) {
MatchingPool.restTemplate = restTemplate;
}
public void addPlayer(Integer userId,Integer rating) {
lock.lock();
try {
players.add(new Player(userId,rating,0));
}finally {
lock.unlock();
}
}
public void removePlayer(Integer userId){
lock.lock();
try {
List<Player> newPlayers = new ArrayList<>();
for (Player player: players) {
if (!player.getUserId().equals(userId)) {
newPlayers.add(player);
}
}
players = newPlayers;
}finally {
lock.unlock();
}
}
private void increaseWaitingTime() {
// 所有等待的用户等待时间加1
for (Player p : players) {
p.setWaitingTime(p.getWaitingTime() + 1);
}
}
// 判断两名玩家是否匹配
private boolean checkMatched(Player a,Player b) {
int ratingDelta = Math.abs(a.getRating() - b.getRating()); // 分差
int waitingTime = Math.min(a.getWaitingTime(),b.getWaitingTime()); // 同时满足两名用户的要求
return ratingDelta < waitingTime * 10;
}
// 尝试匹配玩家
private void matchPlayer() {
System.out.println("match_players: " + players.toString());
boolean[] used = new boolean[players.size()]; // 记录用户是否已经被匹配
for (int i = 0; i < players.size(); i++) {
if (used[i]) continue;
for (int j = i + 1; j < players.size(); j++) {
if (used[j]) continue;
Player a = players.get(i), b = players.get(j);
if (checkMatched(a,b)) {
used[i] = used[j] = true;
sendResult(a,b);
break;
}
}
}
// 删除已经匹配成功的用户
List<Player> newPlayers = new ArrayList<>();
for (int i = 0; i < players.size(); i++) {
if (!used[i]) newPlayers.add(players.get(i));
}
players = newPlayers;
}
// 返回两名玩家的匹配结果
private void sendResult(Player a,Player b) {
System.out.println("send result " + a + " " + b);
MultiValueMap<String,String> data = new LinkedMultiValueMap<>();
data.add("a_id",a.getUserId().toString());
data.add("b_id",b.getUserId().toString());
// 向WebServer返回匹配结果
restTemplate.postForObject(startGameUrl,data,String.class);
}
@Override
public void run() {
while (true) {
try {
Thread.sleep(1000);
lock.lock();
try{
increaseWaitingTime();
matchPlayer();
}finally {
lock.unlock();
}
} catch (InterruptedException e) {
e.printStackTrace();
break;
}
}
}
}

@ -0,0 +1,14 @@
package com.kob.matchingsystem.service.impl.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Player {
private Integer userId;
private Integer rating;
private Integer waitingTime; // 匹配等待的时间
}

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<modules>
<module>matchingsystem</module>
<module>backend</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.kob</groupId>
<artifactId>backendCloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>backendCloud</name>
<description>backendCloud</description>
<properties>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

@ -6,7 +6,7 @@
<img :src="$store.state.user.photo" alt="">
</div>
<div class="username">
<span class="info">用户名:&nbsp;&nbsp;</span>{{ $store.state.user.username }}
{{ $store.state.user.username }}
</div>
</div>
<div class="col-6">
@ -14,7 +14,7 @@
<img :src="$store.state.pk.opponent_photo" alt="">
</div>
<div class="username">
<span class="info">用户名:&nbsp;&nbsp;</span>{{ $store.state.pk.opponent_username }}
{{ $store.state.pk.opponent_username }}
</div>
</div>
<div class="col-12" style="text-align: center; padding-top: 10vh;">
@ -72,10 +72,6 @@ export default {
background-color: rgba(123, 197, 212, 0.5);
}
.info {
font-size: 24px;
color: black;
}
img {
margin-top: 10vh;
@ -88,10 +84,10 @@ img {
}
.username {
margin-top: 40px;
margin-top: 30px;
font-size: 24px;
font-weight: bold;
color:crimson;
color:black;
text-align: center;
}

@ -34,7 +34,7 @@ export default {
store.commit("updateStatus","matching");
store.commit("updateLoser","none");
store.commit("updateOpponent", {
username: "my opponent",
username: "我的对手",
photo:
"https://cdn.acwing.com/media/article/image/2022/08/09/1_1db2488f17-anonymous.png",
});

@ -28,7 +28,7 @@ export default {
// onMountedsetup
onMounted(() => {
store.commit("updateOpponent", {
username: "my opponent",
username: "我的对手",
photo:
"https://cdn.acwing.com/media/article/image/2022/08/09/1_1db2488f17-anonymous.png",
});

Loading…
Cancel
Save