Spring MVC: объединение слушателя и отправителя в Cometd
- Я работаю над приложением Spring-MVC, в котором я хотел бы использовать механизм чата Cometd для GroupChat. Я проверил примеры, и StockPriceEmitter и Client-Side server привет, но есть одна важная вещь, которую я не могу найти в руководствах, это как объединить эти примеры.
- Учебник Ссылка: Ссылка
- Если кто-то знает, как работают примеры, он может пропустить этот абзац. Итак, в основном, как работает серверный клиент на стороне клиента, это приветственное сообщение, отправляемое по служебному каналу '/service/hello', а на стороне сервера оно печатается. StockPriceEmitter работает наоборот, он создает некоторые значения в бэкэнде и отправляет их во внешний интерфейс по определенному каналу.
- Моя проблема в том, что я хотел бы передать сообщение, полученное от клиента, всем подписчикам канала, по сути, объединяя два приведенных выше примера.
Обновить
После отсутствия ответов, как в большинстве случаев, я нашел решение для создания кода, чтобы я мог отправлять и получать сообщения по нескольким каналам, используя Java, Javascript. Вот код, если кому-то требуется:
BayeuxInitializer:
@Component
public class BayeuxInitializer implements DestructionAwareBeanPostProcessor, ServletContextAware
{
private BayeuxServer bayeuxServer;
private ServerAnnotationProcessor processor;
@Inject
private void setBayeuxServer(BayeuxServer bayeuxServer)
{
this.bayeuxServer = bayeuxServer;
}
@PostConstruct
private void init()
{
this.processor = new ServerAnnotationProcessor(bayeuxServer);
}
@PreDestroy
private void destroy()
{
}
public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
{
processor.processDependencies(bean);
processor.processConfigurations(bean);
processor.processCallbacks(bean);
return bean;
}
public Object postProcessAfterInitialization(Object bean, String name) throws BeansException
{
return bean;
}
public void postProcessBeforeDestruction(Object bean, String name) throws BeansException
{
processor.deprocessCallbacks(bean);
}
@Bean(initMethod = "start", destroyMethod = "stop")
public BayeuxServer bayeuxServer()
{
BayeuxServerImpl bean = new BayeuxServerImpl();
// bean.setTransports(new WebSocketTransport(bean), new JSONTransport(bean), new JSONPTransport(bean));
return bean;
}
public void setServletContext(ServletContext servletContext)
{
servletContext.setAttribute(BayeuxServer.ATTRIBUTE, bayeuxServer);
}
}
HelloService:
@Named
@Service("chat")
public class HelloService
{
@Inject
private BayeuxServer bayeux;
@Session
private ServerSession serverSession;
@PostConstruct
public void init()
{
}
// The below is dynamic channel, it will listen to anything like /chat/hello or /chat/weareborg
@Listener("/chat/*")
public void processCheck(ServerSession remote, ServerMessage.Mutable message){
System.out.println("We reached in process check"+message.getData().toString());
Map<String, Object> input = message.getDataAsMap();
String name = (String)input.get("name");
Map<String, Object> output = new HashMap<>();
output.put("greeting", name);
output.put("channelname",message.getChannel());
// remote.deliver(serverSession, "/hello", output);
ServerChannel serverChannel = bayeux.getChannel(message.getChannel());
serverChannel.setPersistent(true);
serverChannel.publish(serverSession, output);
}
}
application.js:
(function($)
{
var cometd = $.cometd;
$(document).ready(function()
{
function _connectionEstablished()
{
// $('#body').append('<div>CometD Connection Established</div>');
}
function _connectionBroken()
{
// $('#body').append('<div>CometD Connection Broken</div>');
}
function _connectionClosed()
{
// $('#body').append('<div>CometD Connection Closed</div>');
}
// Function that manages the connection status with the Bayeux server
var _connected = false;
function _metaConnect(message)
{
if (cometd.isDisconnected())
{
_connected = false;
_connectionClosed();
return;
}
var wasConnected = _connected;
_connected = message.successful === true;
if (!wasConnected && _connected)
{
_connectionEstablished();
}
else if (wasConnected && !_connected)
{
_connectionBroken();
}
}
// Function invoked when first contacting the server and
// when the server has lost the state of this client
function _metaHandshake(handshake)
{
if (handshake.successful === true)
{
cometd.batch(function()
{
cometd.subscribe('/chat/hello', function(message)
{
if(!(message.data.greeting==undefined)) {
/* $.ajax({
url: "/getfirstname",
dataType: "html",
cache: false,
success: function(response ){*/
$('.hello1').append('<div>Server Says: ' + message.data.greeting + ' ' + message.data.channelname + '</div>');
// }
// })
}
});
cometd.publish('/check/hello');
});
}
}
// Disconnect when the page unloads
$(window).unload(function()
{
cometd.disconnect(true);
});
var cometURL = location.protocol + "//" + location.host + config.contextPath + "/cometd";
cometd.configure({
url: cometURL,
logLevel: 'debug'
});
cometd.addListener('/meta/handshake', _metaHandshake);
cometd.addListener('/meta/connect', _metaConnect);
cometd.handshake();
});
})(jQuery);
index.jsp:
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/jquery-2.1.3.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/org/cometd.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/jquery/jquery.cometd.js"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/resources/application.js"></script>
</head>
<body>
<div id="body">
<input id="enterText" type="text" />Enter text
<input id="sendMessage" type="button"/>
</div>
<div class="hello1">
</div>
<div class="hello123">
</div>
<script type="text/javascript">
var config = {
contextPath: '${pageContext.request.contextPath}'
};
var cometd = $.cometd;
/* setInterval(function(){
cometd.batch(function()
{
cometd.subscribe('/hello', function(message) {
$('#body').append('<div>Server Says: ' + message.data.greeting + '</div>');
});
cometd.publish('/service/hello', { name: 'Akshay' });
});
}, 10000);*/
$(document).on("click", "#sendMessage", function(){
var text = $("#enterText").val();
cometd.publish('/chat/hello', { name: text });
// $('#body').append('<div>Server Says: ' + message.data.greeting + '</div>');
});
</script>
</body>
</html>
Пожалуйста, используйте эти зависимости cometd, я заметил конфликты зависимостей для других версий:
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>bayeux-api</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.cometd.javascript</groupId>
<artifactId>cometd-javascript-jquery</artifactId>
<version>3.0.4</version>
<type>war</type>
</dependency>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>cometd-java-server</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.3.0.M2</version>
</dependency>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>cometd-java-client</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>org.cometd.java</groupId>
<artifactId>cometd-java-annotations</artifactId>
<version>3.0.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>9.2.9.v20150224</version>
</dependency>
Выше приведено решение, если есть какие-либо сомнения, пожалуйста, спросите меня.