Skip to content

Commit

Permalink
refactor: job skill 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
thdwoqor committed Dec 25, 2024
1 parent a7cfaa1 commit f3939b4
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 39 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package mafia.mafiatogether.common.config;


import java.util.List;
import lombok.RequiredArgsConstructor;
import mafia.mafiatogether.chat.ui.WebsocketPlayerArgumentResolver;
import mafia.mafiatogether.common.interceptor.ChatInterceptor;
import mafia.mafiatogether.common.interceptor.PathMatcherInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
import org.springframework.messaging.simp.config.ChannelRegistration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.messaging.simp.stomp.StompCommand;
Expand All @@ -30,6 +32,11 @@ public void registerStompEndpoints(StompEndpointRegistry registry) {
);
}

@Override
public void addArgumentResolvers(final List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new WebsocketPlayerArgumentResolver());
}

@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.setApplicationDestinationPrefixes("/pub");
Expand All @@ -40,9 +47,9 @@ public void configureMessageBroker(MessageBrokerRegistry registry) {
public void configureClientInboundChannel(ChannelRegistration registry) {
registry.interceptors(
new PathMatcherInterceptor(chatInterceptor)
.includePathPattern("/chat/**", StompCommand.SUBSCRIBE)
.includePathPattern("/chat/**", StompCommand.DISCONNECT)
.includePathPattern("/chat/**", StompCommand.MESSAGE)
.includePathPattern("/sub/chat/**", StompCommand.SUBSCRIBE)
.includePathPattern("/pub/chat/**", StompCommand.MESSAGE)
.includePathPattern("/pub/chat/**", StompCommand.SEND)
);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,55 +15,56 @@ public class PathMatcherInterceptor implements ChannelInterceptor {

private final ChannelInterceptor channelInterceptor;
private final PathMatcher pathMatcher;
private final List<StompMapping> includePathPattern;
private final List<StompMapping> excludePathPattern;
private final List<StompMapping> includePathPatterns;
private final List<StompMapping> excludePathPatterns;

public PathMatcherInterceptor(
final ChannelInterceptor channelInterceptor
) {
public PathMatcherInterceptor(final ChannelInterceptor channelInterceptor) {
this.channelInterceptor = channelInterceptor;
this.pathMatcher = new AntPathMatcher();
this.includePathPattern = new ArrayList<>();
this.excludePathPattern = new ArrayList<>();
this.includePathPatterns = new ArrayList<>();
this.excludePathPatterns = new ArrayList<>();
}


@Override
public Message<?> preSend(final Message<?> message, final MessageChannel channel) {
StompHeaderAccessor headerAccessor = MessageHeaderAccessor.getAccessor(message, StompHeaderAccessor.class);

if (
if (headerAccessor != null &&
headerAccessor.getDestination() != null &&
notIncludedPath(headerAccessor.getDestination(), headerAccessor.getCommand())
) {
shouldIntercept(headerAccessor.getDestination(), headerAccessor.getCommand())) {
return channelInterceptor.preSend(message, channel);
}

return ChannelInterceptor.super.preSend(message, channel);
}

private boolean notIncludedPath(String destination, StompCommand command) {
boolean excludePattern = excludePathPattern.stream()
.anyMatch(stompMapping -> anyMatchPathPattern(destination, command, stompMapping));
private boolean shouldIntercept(String destination, StompCommand command) {
boolean isExcluded = excludePathPatterns.stream()
.anyMatch(stompMapping -> matchesPathAndCommand(destination, command, stompMapping));

boolean isIncluded = includePathPatterns.stream()
.anyMatch(stompMapping -> matchesPathAndCommand(destination, command, stompMapping));

boolean includePattern = includePathPattern.stream()
.anyMatch(stompMapping -> anyMatchPathPattern(destination, command, stompMapping));
System.out.println("##");
System.out.println("##");
System.out.println(isExcluded);
System.out.println(isIncluded);

return excludePattern || !includePattern;
return isIncluded && !isExcluded;
}

private boolean anyMatchPathPattern(String destination, StompCommand command, StompMapping stompMapping) {
return pathMatcher.match(destination, stompMapping.destination()) &&
private boolean matchesPathAndCommand(String destination, StompCommand command, StompMapping stompMapping) {
return pathMatcher.match(stompMapping.destination(), destination) &&
stompMapping.command() == command;
}

public PathMatcherInterceptor includePathPattern(String targetPath, StompCommand pathMethod) {
this.includePathPattern.add(new StompMapping(targetPath, pathMethod));
public PathMatcherInterceptor includePathPattern(String targetPath, StompCommand command) {
this.includePathPatterns.add(new StompMapping(targetPath, command));
return this;
}

public PathMatcherInterceptor excludePathPattern(String targetPath, StompCommand pathMethod) {
this.excludePathPattern.add(new StompMapping(targetPath, pathMethod));
public PathMatcherInterceptor excludePathPattern(String targetPath, StompCommand command) {
this.excludePathPatterns.add(new StompMapping(targetPath, command));
return this;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package mafia.mafiatogether.chat.ui;

import mafia.mafiatogether.common.annotation.PlayerInfo;
import mafia.mafiatogether.common.exception.AuthException;
import mafia.mafiatogether.common.exception.ExceptionCode;
import mafia.mafiatogether.common.resolver.PlayerInfoDto;
import mafia.mafiatogether.common.util.AuthExtractor;
import org.springframework.core.MethodParameter;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver;
import org.springframework.messaging.simp.SimpMessageHeaderAccessor;

public class WebsocketPlayerArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(final MethodParameter parameter) {
return parameter.hasParameterAnnotation(PlayerInfo.class);
}

@Override
public Object resolveArgument(final MethodParameter parameter, final Message<?> message) throws Exception {
SimpMessageHeaderAccessor headerAccessor = SimpMessageHeaderAccessor.wrap(message);
String authorization = headerAccessor.getFirstNativeHeader("Authorization");
if (authorization == null) {
throw new AuthException(ExceptionCode.MISSING_AUTHENTICATION_HEADER);
}
if (!authorization.startsWith("Basic")) {
throw new AuthException(ExceptionCode.MISSING_AUTHENTICATION_HEADER);
}

String[] information = AuthExtractor.extractByAuthorization(authorization);

return new PlayerInfoDto(information[0], information[1]);
}

}
31 changes: 20 additions & 11 deletions src/main/java/mafia/mafiatogether/job/ui/JobController.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package mafia.mafiatogether.job.ui;


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Base64;
import lombok.RequiredArgsConstructor;
import mafia.mafiatogether.chat.annotation.SendToChatWithRedis;
import mafia.mafiatogether.chat.domain.Message;
import mafia.mafiatogether.common.annotation.PlayerInfo;
import mafia.mafiatogether.common.resolver.PlayerInfoDto;
import mafia.mafiatogether.job.application.JobService;
import mafia.mafiatogether.job.application.dto.request.JobExecuteAbilityRequest;
import mafia.mafiatogether.job.application.dto.response.JobExecuteAbilityResponse;
import mafia.mafiatogether.job.application.dto.response.JobResponse;
import mafia.mafiatogether.job.application.dto.response.JobResultResponse;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.messaging.handler.annotation.DestinationVariable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -25,22 +27,29 @@
@RequestMapping("/jobs")
public class JobController {

private final StringRedisTemplate stringRedisTemplate;
private final ObjectMapper objectMapper;
private final JobService jobService;

@GetMapping("/my")
public ResponseEntity<JobResponse> getJob(@PlayerInfo PlayerInfoDto playerInfoDto) {
return ResponseEntity.ok(jobService.getPlayerJob(playerInfoDto.code(), playerInfoDto.name()));
}

@MessageMapping("/skill/{code}/{name}")
@SendToChatWithRedis("/sub/mafia/{code}")
public Message executeSkill(
@DestinationVariable("code") String code,
@DestinationVariable("name") String name,
@MessageMapping("/jobs/skill")
public void executeWebSocketSkill(
@PlayerInfo PlayerInfoDto playerInfoDto,
@Payload JobExecuteAbilityRequest request
) {
JobExecuteAbilityResponse response = jobService.executeSkill(code, name, request);
return Message.ofChat(response.job(), response.result());
) throws JsonProcessingException {
JobExecuteAbilityResponse response = jobService.executeSkill(playerInfoDto.code(), playerInfoDto.name(),
request);
String auth = Base64.getEncoder()
.encodeToString((playerInfoDto.code() + ":" + playerInfoDto.name()).getBytes());

stringRedisTemplate.convertAndSend(
String.format("/sub/job/skill/%s/%s", response.job().toLowerCase(), auth),
objectMapper.writeValueAsString(response)
);
}

@PostMapping("/skill")
Expand Down
20 changes: 20 additions & 0 deletions src/main/resources/static/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ stompClient.onConnect = (frame) => {
stompClient.subscribe('/sub/chat/aGVsbG86cG93ZXJhc3M=', (greeting) => {
showGreeting(JSON.parse(greeting.body));
});

stompClient.subscribe('/sub/job/skill/mafia/aGVsbG86cG93ZXJhc3M=', (greeting) => {
showSkill(JSON.parse(greeting.body));
});
};

stompClient.onWebSocketError = (error) => {
Expand Down Expand Up @@ -59,16 +63,32 @@ function leaveRoom() {
});
}

function executeSkill() {
stompClient.publish({
destination: "/pub/jobs/skill",
body: JSON.stringify({'target': $("#target").val()}),
headers: {
Authorization: 'Basic aGVsbG86cG93ZXJhc3M=',
},
});
}

function showGreeting(message) {
console.log('Received: ' + JSON.stringify(message));
$("#greeting").append("<tr><td>" + JSON.stringify(message) + "</td></tr>");
}

function showSkill(message) {
console.log('Received: ' + JSON.stringify(message));
$("#greeting").append("<tr><td>" + JSON.stringify(message) + "</td></tr>");
}

$(function () {
$("form").on('submit', (e) => e.preventDefault());
$("#connect").click(() => connect());
$("#disconnect").click(() => disconnect());
$("#send").click(() => sendName());
$("#enter").click(() => enterRoom());
$("#leave").click(() => leaveRoom());
$("#skill").click(() => executeSkill());
});
9 changes: 8 additions & 1 deletion src/main/resources/static/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,13 @@
<button id="enter" class="btn btn-default" type="submit">Enter</button>
<button id="leave" class="btn btn-default" type="submit">Leave</button>
</form>
<div>
<div class="form-group">
<label for="name">What is your target?</label>
<input type="text" id="target" class="form-control" placeholder="Your target here...">
</div>
<button id="skill" class="btn btn-default" type="submit">Skill</button>
</div>
</div>
</div>
<div class="row">
Expand All @@ -51,4 +58,4 @@
</div>
</div>
</body>
</html>
</html>

0 comments on commit f3939b4

Please sign in to comment.