我正在尝试使用Angular 2(而不是AngularJS)作为客户端技术来实现Vert.x chat example。对于WebSocket的客户端实现,我遵循了this GitHub repo提出的准则。 Angualr 2和AngularJS应用程序之间的主要区别在于,第一个不能在Vert.x服务器的同一端口上运行。
主要问题是,当我发送消息时,服务器未收到该消息。另一个问题是在onPostExecute
配置中:我无法接受来自本地主机的所有传入连接(我尝试使用CorsHandler
却没有成功)。
Vert.x Server.java
"http://localhost:*"
app.component.ts
package io.vertx.example.web.chat;
import java.text.DateFormat;
import java.time.Instant;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.eventbus.DeliveryOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.http.HttpMethod;
import io.vertx.example.util.Runner;
import io.vertx.ext.bridge.PermittedOptions;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.CorsHandler;
import io.vertx.ext.web.handler.impl.CorsHandlerImpl;
import io.vertx.ext.web.handler.sockjs.BridgeOptions;
import io.vertx.ext.web.handler.sockjs.SockJSHandler;
public class Server extends AbstractVerticle {
// Convenience method so you can run it in your IDE
public static void main(String[] args) {
Runner.runExample(Server.class);
}
@Override
public void start() throws Exception {
Router router = Router.router(vertx);
Set<String> allowedHeaders = new HashSet<>();
allowedHeaders.add("x-requested-with");
allowedHeaders.add("Access-Control-Allow-Origin");
allowedHeaders.add("origin");
allowedHeaders.add("Content-Type");
allowedHeaders.add("accept");
allowedHeaders.add("X-PINGARUNER");
Set<HttpMethod> allowedMethods = new HashSet<>();
allowedMethods.add(HttpMethod.GET);
allowedMethods.add(HttpMethod.POST);
allowedMethods.add(HttpMethod.OPTIONS);
allowedMethods.add(HttpMethod.DELETE);
allowedMethods.add(HttpMethod.PATCH);
allowedMethods.add(HttpMethod.PUT);
CorsHandler corsHandler = new CorsHandlerImpl("http://localhost:4200");
corsHandler.allowedHeaders(allowedHeaders);
corsHandler.allowedMethods(allowedMethods);
corsHandler.allowCredentials(true);
router.route().handler(corsHandler);
// Allow events for the designated addresses in/out of the event bus bridge
BridgeOptions opts = new BridgeOptions()
.addInboundPermitted(new PermittedOptions().setAddress("chat.to.server"))
.addOutboundPermitted(new PermittedOptions().setAddress("chat.to.client"));
// Create the event bus bridge and add it to the router.
SockJSHandler ebHandler = SockJSHandler.create(vertx).bridge(opts);
router.route("/eventbus/*").handler(ebHandler);
router.route("/socket.io/*").handler(ebHandler);
EventBus eventBus = vertx.eventBus();
// Register to listen for messages coming IN to the server
eventBus.consumer("chat.to.server").handler(message -> {
System.out.println("consuming message");
// Create a timestamp string
String timestamp = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM)
.format(Date.from(Instant.now()));
DeliveryOptions d = new DeliveryOptions();
d.addHeader("Access-Control-Allow-Origin", "true");
// Send the message back out to all clients with the timestamp prepended.
eventBus.publish("chat.to.client", timestamp + ": " + message.body());
});
// Start the web server and tell it to use the router to handle requests.
vertx.createHttpServer().requestHandler(router::accept).listen(8080);
System.out.println("Chat server running");
}
}
chat.service.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ChatService } from './chat.service';
@Component({
selector: 'app-root',
template: `<div *ngFor="let message of messages">
{{message.text}}
</div>
<button (click)="sendMessage()">Send</button>`,
styleUrls: ['./app.component.css'],
})
export class AppComponent implements OnInit, OnDestroy {
messages = [];
connection;
message;
constructor(private chatService: ChatService) { }
sendMessage() {
this.chatService.sendMessage(this.message);
this.message = '';
}
ngOnInit() {
this.connection = this.chatService.getMessages().subscribe(message => {
console.log("received");
console.log(message);
this.messages.push(message);
})
}
ngOnDestroy() {
this.connection.unsubscribe();
}
send(event) {
console.log(event);
if (event.charCode == 13) {
}
}
}