我需要实现RPC over STOMP,其中客户端在浏览器中使用javascript运行,服务器端使用Spring消息传递功能实现.
虽然使用@MessageMapping对于正常消息传递很好,但我发现使用@SendToUser非常限制实现RPC,因为当客户端发出多个同时请求时,客户端很难理解哪个回复与场景中的哪个请求相关联.
当然只有一个请求就没有问题,并且客户端等待它的回复,但是当客户端必须跟踪多个"开放"rpc调用时会出现问题.
通过将ID与每个请求相关联,我设法使系统变得更好,即:客户端将id与消息一起发送,并且服务器回复包含此id的特殊消息包装器,因此客户端能够将异步回复与请求相关联.
这很好但有几个限制:
我必须开发需要理解这种结构的代码,并且这使得uitlity无法使用简单的带注释的方法
当服务器端代码生成异常时,调用Spring @MessageExceptionHandler并将正确的异常返回给客户端,但请求ID丢失,因为处理程序没有(简单)方法来访问它.
我知道使用rabbitmq我们可以为每个需要与特殊回复(rpc响应)关联的请求添加"reply-to"标头,这是通过创建用户自动订阅的特殊临时队列来实现的,但是我如何在Spring中使用这个方案呢?此外,这将使我成为一个特定的经纪人.
我怎样才能在Spring中优雅地实现正确的RPC调用,正确处理服务器端异常?
我发现这是一个普遍的问题,我认为Spring可以大大有益于本地实现它.
当Facebook发送实时更新时,它们在HTTP标头中包含X-Hub-Signature.根据他们的文档,他们使用SHA1和应用程序密钥作为密钥.
根据C#的类似问题,我尝试验证这样的签名('body'是facebook在请求正文中发送的消息):
String passedSignature = req.getHeader("X-Hub-Signature").substring(5);
Mac hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(FACEBOOK_SECRET.getBytes(Charset.forName("UTF-8")), "HmacSHA1"));
String calculatedSignature = Hex.encodeHexString(hmac.doFinal(body.getBytes(Charset.forName("UTF-8"))));
logger.debug("Calculated sigSHA1: " + calculatedSignature + " passedSignature: " + passedSignature);
Run Code Online (Sandbox Code Playgroud)
但passSignature总是与calculatedSignature不同.
有人可以帮忙解决问题吗?
假设我们有一个这种类型的实体:
@Entity
@Table(name="User")
public class User {
@Id
long id;
@ElementCollection
List<String> phones;
}
Run Code Online (Sandbox Code Playgroud)
我的目标是为所有用户提供完整的电话列表,例如:“SELECT x.phones FROM User x”
我尝试构建这种类型的 Spring Data JPA 查询:
@Query("SELECT x.phones FROM User x")
List<String> findAllPhones();
Run Code Online (Sandbox Code Playgroud)
但我得到这个例外:
org.hibernate.QueryException: 不是实体
在 org.hibernate.hql.internal.ast.tree.FromElementType.renderIdentifierSelect(FromElementType.java:188)
我不得不求助于本机 sql 查询来解决这个问题。否则我必须将电话号码包装在一个新实体中,但我确实想避免这种情况。
有没有办法使用普通 JPA 或(甚至更好)仅使用 Spring Data JPA 方法来解决此类问题?
我正在开发一个通过WebSocket使用STOMP消息传递的Spring Boot应用程序,该应用程序实现了RPC模式,该模式公开了公共(即,无需身份验证)和私有方法。
存在两个公共方法来注册和验证用户,因此我需要手动(以编程方式)处理用户登录,该方法通过自定义@MessageMapping操作访问。
问题是:如何验证Websocket会话的用户?
为了使用普通的MVC Web应用程序做类似的事情,我将使用类似于以下的代码:
@MessageMapping("/auth")
public Object auth() {
List<GrantedAuthority> authorities = AuthorityUtils.createAuthorityList("ROLE_TEST");
SecurityContextHolder.getContext().setAuthentication(new PreAuthenticatedAuthenticationToken(myname, "dummy", authorities));
}
Run Code Online (Sandbox Code Playgroud)
但这在websocket环境中似乎不起作用,因为当用户使用以下方法时:
@MessageMapping("/myendpoint")
public Object myEndpoint(Param params, Principal principal) {...}
Run Code Online (Sandbox Code Playgroud)
我得到错误:
org.springframework.messaging.simp.annotation.support.MissingSessionUserException: No "user" header in message
Run Code Online (Sandbox Code Playgroud)
所以问题是:如何在auth()方法中手动验证用户,以便在myEndpoint()中正确解析Principal参数?
stomp spring-security websocket spring-boot spring-websocket
我想要与此 XML 配置等效的内容(在此处获取),但使用 Java 配置:
<bean id="customHandler" class="app.wsock.CustomHandler"/>
<websocket:message-broker application-destination-prefix="/app">
<websocket:stomp-endpoint path="/foo">
<websocket:handshake-handler ref="customHandler"/>
</websocket:stomp-endpoint>
<websocket:simpl-broker prefix="/topic,/queue" />
</websocket:message-broker>
Run Code Online (Sandbox Code Playgroud)
我的目标是构建一个类,根据某些标准限制与我的 STOMP 端点(即:他的 websocket)的连接。
我不想使用 XML 来配置我的端点,如何将该代码段转换为 Java Config?
java ×3
stomp ×3
spring ×2
facebook ×1
jpa ×1
rpc ×1
sha ×1
spring-boot ×1
spring-data ×1
websocket ×1