如何将命令提示符下运行的客户端 - 服务器聊天应用程序转换为基于Web的应用

时间:2016-05-16 12:44:56

标签: java sockets tomcat client-server chat

我使用套接字编程创建了多个客户端 - 服务器聊天应用程序,我可以在命令提示符下将其部署为JAR文件。现在我需要做些什么来改变才能使用tomcat服务器在Web浏览器上运行这个应用程序?

我的服务器代码:

package com.Aricent;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.*;
import java.sql.DriverManager;

public class Server {

    static ServerSocket serverSocket=null;
    static Socket clientSocket=null;
    static final int max=20;
    static clientThread[] threads=new clientThread[max];
    public static void main(String arg[])
    {
        int portNumber=2222;
        try{
        serverSocket=new ServerSocket(portNumber);
        }catch(IOException e)
        {
            System.out.println(e);
        }

        while(true)
        {
            try{
                clientSocket=serverSocket.accept();
                int i=0;
                for(i=0;i<max;i++)
                {
                    if(threads[i]==null)// searching for empty position
                    {
                        (threads[i]=new clientThread(clientSocket, threads)).start();
                        break;
                    }
                }
                if(i==max)
                {
                    PrintStream os=new PrintStream(clientSocket.getOutputStream());
                    os.println("Server too busy. Try later");
                    os.close();
                    clientSocket.close();
                }
            }catch(IOException e)
            {
                System.out.println(e);
            }
        }
    }

}


class clientThread extends Thread
{
    String clientName=null;
    DataInputStream is=null;
    PrintStream os=null;
    Socket clientSocket=null;
    clientThread[] threads;
    int max;
    String dbPath="jdbc:mysql://172.19.24.66:3306/chatdb";
    String dbUser="root";
    String dbPass="root";

    public clientThread(Socket clientSocket, clientThread[] threads)
    {
        this.clientSocket=clientSocket;
        this.threads=threads;
        max=threads.length;
    }

    public void run()
    {

        int max=this.max;
        clientThread[] threads=this.threads;
        boolean choice=false;
        String sender="";



        try{
            Class.forName("com.mysql.jdbc.Driver");
            Connection con=DriverManager.getConnection(dbPath,dbUser,dbPass);
            PreparedStatement ps=null;
            ResultSet rs=null;
            Statement stmt=con.createStatement();
            String query="";


            is=new DataInputStream(clientSocket.getInputStream());
            os=new PrintStream(clientSocket.getOutputStream());
            String name="";
            String ch="";
            boolean login=false;
            while(!login)
            {
                os.println("*** Press 1 to login or press 2 to register***");
                ch=is.readLine();
                os.println(ch);
                if(ch.equals("1"))
                {
                    os.println("Enter your username and password...");
                    String uname=is.readLine();
                    String upass=is.readLine();
                    query="Select * from user where username= '"+uname+"' and password= '"+upass+"'";
                    rs=stmt.executeQuery(query);
                    if(rs.next() && !rs.getString("status").equals("online"))
                    {
                        query="update user set status='online' where username='"+uname+"'";
                        stmt.executeUpdate(query);
                        login=true;
                        name=uname;
                    }
                    else
                        os.println("Sorry wrong credentials");
                }
                else if(ch.equals("2"))
                {
                    os.println("Enter your username and password and emailId for registration...");
                    String uname=is.readLine();
                    String upass=is.readLine();
                    String uemail=is.readLine();
                    query="Select username from user where emailId= '"+uemail+"'";
                    rs=stmt.executeQuery(query);
                    if(rs.next() )
                    {
                        os.println("Sorry user- "+rs.getString("username")+" already registered with this mail id");

                    }
                    else
                    {
                        query="insert into user (username,password,emailId,status) value('"+uname+"','"+upass+"','"+uemail+"','offline')";
                        stmt.executeUpdate(query);
                        os.println("Registration successful...");
                    }
                }
                else
                    os.println("Wrong input");
            }






            os.println("Welcome "+ name+" to chat room. \n To leave enter: /stop \n To start private chat enter: /Private USERNAME YOUR MESSAGE \n To stop private chat enter: /endPrivate");
            synchronized(this){
                for(int i=0;i<max;i++)
                {
                    if(threads[i]!=null && threads[i]==this){
                        clientName=name;
                        break;
                    }
                }

                for(int i=0;i<max;i++)
                {
                    if(threads[i]!=null&& threads[i]!=this)
                    {
                        threads[i].os.println("*NEW USER "+name+" ENTERed CHAT ROOM*");

                    }
                }
            }

            while(true)
            {
                int pos=0;
                String line=is.readLine();
                if(line.startsWith("/stop"))
                {
                    break;
                }
                if(line.startsWith("/endPrivate"))
                {
                    choice=false;

                }
                if(line.startsWith("/Private") || choice==true )
                {
                    choice=true;
                    //String words[];
                    if(line.startsWith("/Private"))
                    {
                        //pos=2;
                         String words[]=line.split("\\s",3);
                         sender=words[1];
                        synchronized(this)
                        {
                            for(int i=0;i<max;i++)
                            {
                                if(threads[i]!=null && threads[i]!=this && threads[i].clientName.equals(words[1]) )
                                {
                                    threads[i].os.println("<"+name+">"+words[2]);
                                    this.os.println(">>"+name+" "+words[2]); //showing the sender that msg is sent
                                    break;
                                }
                            }
                        }

                    }
                    else
                    {
                    String words[]=line.split("\\s",1);
                    synchronized(this)
                    {
                        for(int i=0;i<max;i++)
                        {
                            if(threads[i]!=null && threads[i]!=this && threads[i].clientName.equals(sender) )
                            {
                                threads[i].os.println("<"+name+">"+words[0]);
                                this.os.println(">>"+name+" "+words[0]); //showing the sender that msg is sent
                                break;
                            }
                        }
                    }
                    }
                    }
                else
                {
                    synchronized(this){
                        for(int i=0;i<max;i++)
                        {
                            if(threads[i]!=null  && threads[i].clientName!=null )
                            {
                                threads[i].os.println("< "+name+" > "+line);
                                //threads[i].os.println("** The user "+name+" is leaving the chat room **");
                            }
                        }

                    }
                }
            }

            //after while
            synchronized(this)
            {
                for(int i=0;i<max;i++)
                {
                    if(threads[i]!=null  && threads[i].clientName!=null )
                    {

                        threads[i].os.println("** The user "+name+" is leaving the chat room **");
                    }
                }
            }
                    os.println("** Bye "+name+" **");

                    synchronized(this)
                    {
                        for(int i=0;i<max;i++)
                        {
                            if(threads[i]==this)
                            {
                                threads[i]=null;
                            }




                }


            }
                    is.close();
                    os.close();
                    clientSocket.close();





        }catch(Exception e)
        {
            System.out.println(e);
        }




    }

}

客户代码:

package com.Aricent;

import java.io.*;
import java.net.*;

public class Client implements Runnable {

    static Socket clientSocket=null;
    static PrintStream os=null;
    static DataInputStream is=null;
    static BufferedReader inputLine=null;
    static boolean closed=false;

    public static void main(String arg[])
    {
        int portNumber=2222;
        String host="localhost";

        try{
            clientSocket=new Socket(host,portNumber);
            inputLine=new BufferedReader(new InputStreamReader(System.in));
            os=new PrintStream(clientSocket.getOutputStream());
            is=new DataInputStream(clientSocket.getInputStream());

        }
        catch(Exception e)
        {
            System.out.println(e);
        }

        if(clientSocket!=null&&os!=null&&is!=null)
        {
            try{
                new Thread(new Client()).start();
                while(!closed)
                {
                    os.println(inputLine.readLine().trim());
                }
                os.close();
                is.close();
                clientSocket.close();
            }catch(IOException e)
            {
                System.out.println(e);
            }
        }

    }





    //@Override
    public void run() {
        // TODO Auto-generated method stub

        String responseLine;
        try{
            while((responseLine=is.readLine())!=null)
            {
                System.out.println(responseLine);
                if(responseLine.indexOf("*** Bye")!=-1)
                    break;
            }
            closed=true;
        } catch(Exception e)
        {
            System.out.println(e);
        }

    }


}

我的主要问题是如何在本地tomcat服务器中引入套接字编程?

3 个答案:

答案 0 :(得分:4)

几年前我发布了完整的解决方案,但它使用nodejs作为服务器。 Building a chat app that uses a node.js server in IOS。此应用程序使用服务器推送技术(Web套接字)。

如果您想要迁移当前的代码是浏览器,那么只需要调整服务器线程以便从浏览器使用HTTP,您将有几周的工作时间。浏览器通过HTTP协议与服务器通信,该协议比当前解决方案高一层。您的解决方案是使用普通的网络套接字。

但是,您可以在Tomcat和普通Web应用程序上构建一个长轮询类型的应用程序,该应用程序会反复检查服务器是否有新的聊天消息(每隔几秒发出一次新请求),或者尝试使用最新的Tomcat Websocket支持。 Tomcat的示例中有示例聊天应用程序。下载zip,请参阅/apache-tomcat-8.0.35/webapps/examples/websocket /.

答案 1 :(得分:2)

您的应用程序根本不依赖任何标准协议。因此,您必须使用Javascript从头开始重新创建客户端(使其成为Web应用程序)。使用javascript从浏览器进行直接套接字连接将是一个问题(一旦你离开localhost连接,你将受到浏览器安全限制)。

作为一种前瞻性的方法:将服务器作为jar应用程序运行,然后运行客户端 - 自定义Applet(哦!就是90年代 - 00年代)。我想在一两年内,Applet就会过时了。

如果使用更标准的东西重写应用程序会更好,比如STOMP over WebSockets。然后您的服务器可以部署到像Tomcat或Jetty这样的servlet容器中。而您的客户端将是支持websockets和STOMP的任何东西。

据我所见,您的应用程序具有身份验证和聊天室。最好是向自定义框架提供身份验证和授权(您喜欢的任何内容,只需在websocket连接中提供额外的标头以合并WS连接和已建立的会话)。 STOMP单词中的聊天室成为目的地。因此,您需要创建对抵达目的地的邮件做出反应的应用程序。

我建议您查看spring框架及其对websockets的支持。

另外,我看到你正在为每个用户会话建立单独的数据库连接,一般来说是资源的大量使用。创建连接池并仅在需要时使用其中一个。

答案 2 :(得分:1)

如果您使用NPM,则可以使用 pusherjs Pusherjs 有一个免费的计划,它消除了创建和管理套接字连接的麻烦。可以为每个用户分配单独的频道(免费计划支持无限制频道),只需要将消息提交到该频道,您就可以让客户端应用程序持续收听该频道。它非常容易。