[lucene系列笔记3]用socket把lucene做成一个web服务

上一篇介绍了用lucene建立索引和搜索,但是那些都只是在本机上运行的,如果希望在服务器上做成web服务该怎么办呢?

一个有效的方法就是用socket通信,这样可以实现后端与前端的独立,也就是不管前端用什么(比如PHP)都可以Lucene只提供检索功能。

 

简单来说,socket就是实现不同的进程之间通讯的一个通道。socket由两部分组成:服务端和客户端。有两种:单进程和多进程。

 

所以认识socket的阶梯大概是这样的:

1.用java本地做服务端和客户端,实现不同程序之间的单进程通讯;

2.用java在web服务器做服务端,用java本地做客户端,实现不同机器之间的单进程通讯;

3.用java在web服务器做服务端,用PHP在服务器做客户端,实现外网通过PHP网页使用服务(单进程);

4.用java在web服务器做服务端,用PHP在服务器做客户端,实现外网通过PHP网页使用服务(多进程);

 

下面,这篇文章先介绍第一个:用java本地做服务端和客户端,实现不同程序之间的单进程通讯。

 

 

继续上一篇的LuceneTools工程,在里面new一个class命名为LocalSocketServer。

然后在里面加入如下代码(服务端):

import java.nio.file.Paths;
import java.io.*;
import java.net.*;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

/**
 * @author song
 * @description: 
 * 依赖jar:Lucene-core,lucene-analyzers-common,lucene-queryparser
 * 作用:使用索引搜索文件
 */
public class LocalSocketServer {
    public static Version luceneVersion = Version.LATEST;
    /**
     * 查询内容
     */
    public static String indexSearch(String keywords){
        String res = "";
        DirectoryReader reader = null;
        try{
//            1、创建Directory
             Directory directory = FSDirectory.open(Paths.get("D:/lucenetest/index"));//在硬盘上生成Directory
//            2、创建IndexReader
             reader = DirectoryReader.open(directory);
//            3、根据IndexWriter创建IndexSearcher
             IndexSearcher searcher =  new IndexSearcher(reader);
//            4、创建搜索的query
//            创建parse用来确定搜索的内容,第二个参数表示搜索的域
             QueryParser parser = new QueryParser("content",new StandardAnalyzer());//content表示搜索的域或者说字段
             Query query = parser.parse(keywords);//被搜索的内容
//            5、根据Searcher返回TopDocs
             TopDocs tds = searcher.search(query, 20);//查询20条记录
//            6、根据TopDocs获取ScoreDoc
             ScoreDoc[] sds = tds.scoreDocs;
//            7、根据Searcher和ScoreDoc获取搜索到的document对象
             int cou=0;
             for(ScoreDoc sd:sds){
                 cou++;
                 Document d = searcher.doc(sd.doc);
//                    8、根据document对象获取查询的字段值
                 /**  查询结果中content为空,是因为索引中没有存储content的内容,需要根据索引path和name从原文件中获取content**/
                 res+=cou+". "+d.get("path")+" "+d.get("name")+" "+d.get("content")+"\n";
             }

            
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //9、关闭reader
            try {
                reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return res+"hehehehe";
    }
    public static void main(String[] args) throws IOException
    {
        ServerSocket server=new ServerSocket(5678);
        while (true)
        {
            Socket client=server.accept();
            BufferedReader in=new BufferedReader(new InputStreamReader(client.getInputStream()));
            PrintWriter out=new PrintWriter(client.getOutputStream());
            String str=in.readLine();
            System.out.println(str);
            out.println(indexSearch(str));
            out.flush();
            client.close();
        }
    }
}

我们就用上一篇做好的索引来提供服务。

 

然后客户端我们也用java。在工程里new一个class命名为LocalSocketClient。加入如下代码:

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

public class LocalSocketClient
{
        static Socket server;
        public static void main(String[] args)throws Exception
        {
            //如果127.0.0.1不行可以换成InetAddress.getLocalHost()
            server=new Socket("127.0.0.1",5678);
            BufferedReader in=new BufferedReader(new InputStreamReader(server.getInputStream()));
            PrintWriter out=new PrintWriter(server.getOutputStream());
            BufferedReader wt=new BufferedReader(new InputStreamReader(System.in));
            String str=wt.readLine();
            out.println(str);
            out.flush();
            String res=in.readLine();
            while (!res.equals("hehehehe"))
            {
                System.out.println(res);
                res=in.readLine();
            }
            out.flush();
            server.close();
        }
}

 

然后先运行起服务端程序,然后跑起来以后再运行客户端程序,在客户端输入查询即可得到反馈结果。

 

至此,我们学会了单进程,本地socket+Lucene提供服务。(提示:由于上面的服务端程序设置的是无限循环,所以一定要手动结束程序!)

posted @ 2016-11-26 17:04  lvmememe  阅读(730)  评论(0编辑  收藏  举报