12

我正在使用 Java8 并且有一个可以在我的localhost上完美运行的聊天服务器,但是当我将它部署到 OpenShift 服务器时,我收到以下错误:

java.net.SocketException:权限被拒绝

2016-09-05 10:36:11,300 INFO  [stdout] (Thread-125) Starting Chat server on localhost:8000 ...
2016-09-05 10:36:13,194 ERROR [stderr] (Thread-125) Exception in thread "Thread-125" java.net.SocketException: Permission denied
2016-09-05 10:36:13,194 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind0(Native Method)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind(Net.java:433)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.Net.bind(Net.java:425)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223)
2016-09-05 10:36:13,195 ERROR [stderr] (Thread-125)     at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:125)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.AbstractChannel$AbstractUnsafe.bind(AbstractChannel.java:476)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelPipeline$HeadHandler.bind(DefaultChannelPipeline.java:1000)
2016-09-05 10:36:13,196 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelHandlerContext.invokeBind(DefaultChannelHandlerContext.java:463)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelHandlerContext.bind(DefaultChannelHandlerContext.java:448)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.DefaultChannelPipeline.bind(DefaultChannelPipeline.java:842)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.channel.AbstractChannel.bind(AbstractChannel.java:195)
2016-09-05 10:36:13,197 ERROR [stderr] (Thread-125)     at io.netty.bootstrap.AbstractBootstrap$2.run(AbstractBootstrap.java:338)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:370)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:353)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:116)
2016-09-05 10:36:13,198 ERROR [stderr] (Thread-125)     at java.lang.Thread.run(Thread.java:745)

我在这里查看了 OpenShift web sockets guide ,其中说应该使用端口 8000。但我仍然得到错误。

在 Openshift 上,我在WildFly Application Server 10卡式盒上运行我的聊天服务器。

任何建议表示赞赏。

这是我的代码:

WebAppInitializer.java

    try {
        new Thread() {
            public void run() {
                com.jobs.spring.chat.Server chatServer = new com.jobs.spring.chat.Server();
                chatServer.startServer();
            }
        }.start();
    } catch (Exception e) {
        e.printStackTrace();
    }

服务器.java

import java.net.Socket;

import com.corundumstudio.socketio.AckRequest;
import com.corundumstudio.socketio.Configuration;
import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.listener.ConnectListener;
import com.corundumstudio.socketio.listener.DataListener;
import com.corundumstudio.socketio.listener.DisconnectListener;
import com.fasterxml.jackson.databind.ObjectMapper;

/**
 * https://blog.openshift.com/paas-websockets/
 * @author Richard
 *
 */
public class Server {

    //private static final String SERVER = "localhost";
    private static final String SERVER = "jbosswildfly-easyjobs.rhcloud.com";
    private static final Integer PORT = 8000;

    public static void main(String[] args) {
        startServer();
    }

    public static void startServer() {
        Configuration config = new Configuration();
        config.setHostname(SERVER);
        config.setPort(PORT);
        final SocketIOServer server = new SocketIOServer(config);

        server.addConnectListener(new ConnectListener() {
            @Override
            public void onConnect(SocketIOClient client) {
                System.out.println("onConnected");
                client.sendEvent("chat_message:message", new Message("Welcome to the chat!"));
            }
        });

        server.addDisconnectListener(new DisconnectListener() {
            @Override
            public void onDisconnect(SocketIOClient client) {
                System.out.println("onDisconnected");
            }
        });

        server.addEventListener("chat_message:send", String.class, new DataListener<String>() {
            @Override
            public void onData(SocketIOClient client, String data, AckRequest ackSender) throws Exception {
                Message message = null;
                try {
                    message = new ObjectMapper().readValue(data.toString(), Message.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                message.setDate(System.currentTimeMillis());
                server.getBroadcastOperations().sendEvent("chat_message:message", message);
            }
        });

        System.out.println("Starting Chat server on " + SERVER + ":" + PORT+" ...");
        server.start();
        System.out.println("Chat server started");
        System.out.println("Chat server Environment Info: " + System.getenv());
        try {
            Socket socket = new Socket(SERVER, PORT);
            printSocketInformation(socket);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Prints debug output (to stdout) for the given Java Socket.
     */
    public static void printSocketInformation(Socket socket) {
        try {
            System.out.format("Port:                 %s\n", socket.getPort());
            System.out.format("Canonical Host Name:  %s\n", socket.getInetAddress().getCanonicalHostName());
            System.out.format("Host Address:         %s\n\n", socket.getInetAddress().getHostAddress());
            System.out.format("Local Address:        %s\n", socket.getLocalAddress());
            System.out.format("Local Port:           %s\n", socket.getLocalPort());
            System.out.format("Local Socket Address: %s\n\n", socket.getLocalSocketAddress());
            System.out.format("Receive Buffer Size:  %s\n", socket.getReceiveBufferSize());
            System.out.format("Send Buffer Size:     %s\n\n", socket.getSendBufferSize());
            System.out.format("Keep-Alive:           %s\n", socket.getKeepAlive());
            System.out.format("SO Timeout:           %s\n", socket.getSoTimeout());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

这个链接中,OpenShift 讨论了端口绑定和代理。我真的不明白这一切。看起来我应该使用端口 8000(我就是),但我不清楚我应该使用什么主机名。我正在使用我的应用程序 URL 名称 (jbosswildfly-easyjobs.rhcloud.com)。那是对的吗?

如果我将地址更改为,http://jbosswildfly-easyjobs.rhcloud.com(即前缀http://)我收到以下错误:

java.net.SocketException:未解析的地址

在此处输入图像描述

4

2 回答 2

2

我试图找出解决方案。我有一些解决方案。所有人都建议添加-Djava.net.preferIPv4Stack=true到 VM 选项中。

Atlassian 文档还得到了下面给出的根本原因和解决方案:

原因

  1. 根据这篇文章,这是 Java 7 的已知问题之一。
  2. 这也可能是由服务器上安装的任何防病毒或防火墙软件引起的。

解析度

  1. 使用-Djava.net.preferIPv4Stack=trueJVM 系统属性来帮助在 Java 7 上启用对 IPv4 的支持。
  2. 检查服务器上的防病毒和防火墙软件是否没有阻止 Stash 连接到邮件服务器的能力。

此解决方案适用于 Java 7,但您使用的是 Java 8。所以我查找了您的堆栈跟踪。有一条线

 at io.netty.channel.socket.nio.NioServerSocketChannel.doBind(NioServerSocketChannel.java:125)

这说明您正在使用netty

但是netty对版本有一些要求。也有一些限制。

JDK 5 (Netty 3.x) 或 6 (Netty 4.x) 就足够了。某些组件(例如 HTTP/2)可能有更多要求

Netty 4.x 的要求(链接

Java 目前不支持 ALPN 或 NPN(有一个跟踪问题,所以去投票吧!)。由于 JDK 缺乏支持,我们需要为 OpenJDK 使用 Jetty-ALPN(或 Jetty-NPN,如果在 Java < 8 上)引导类路径扩展。为此,添加一个 Xbootclasspath JVM 选项,引用 Jetty alpn-boot jar 的路径。

java -Xbootclasspath/p:/path/to/jetty/alpn/extension.jar ...

请注意,您必须使用特定于您正在使用的 Java 版本的 Jetty-ALPN jar版本。

JDK密码

Java 7 不支持HTTP2 RFC推荐的密码套件。为了解决这个问题,我们建议服务器尽可能使用 Java 8 或使用替代的 JCE 实现,例如Bouncy Castle。如果这不切实际,则可以使用其他密码,但您需要确保您打算调用的服务也支持 HTTP/2 RFC 禁止的这些密码,并已评估这样做的安全风险。

启用 ALPN 或 NPN

SslContextBuilder有一个用于配置 ALPN 或 NPN的ApplicationProtocolConfig的设置器。有关NPN 使用的 ALPN 和SPDY 示例,请参阅HTTP/2 示例。

有关详细说明,您可以通过此链接

建议:

因此,请检查您的 netty 版本并根据上述问题做出决定。或者尽可能使用 JDK 7。

于 2016-09-06T15:02:14.117 回答
2

链接的博客文章说,您可以使用端口 8000 和 8443 连接到 OpenShift 上的 websocket。但是,服务器本身只需绑定到端口8080,然后您就可以外部连接到上面的 ws 端口。您已经找到的这张图解释了配置。

WildFly 已经在使用 8080,因此您可能想要使用DIY 墨盒来部署您的应用程序(不要忘记在 8080 上运行的启动操作挂钩中禁用默认的 ruby​​ 服务器)或在此处获得启发。

于 2016-09-07T14:09:07.433 回答