编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

springboot整合websocket、solr(springboot整合rocketMQ)

wxchong 2024-10-23 15:51:01 开源技术 10 ℃ 0 评论

一. 整合websocket

1.1长连接和短连接

1.2 springboot整合websocket

第一步:导入包

第二步:编写配置类

第三步:编写简单代码:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-websocket</artifactId>

</dependency>

@Configuration

public class WebSocketConfig {

@Bean

public ServerEndpointExporter serverEndpointExporter() {

return new ServerEndpointExporter();

}

}

@ServerEndpoint(value = "/websocket")

@Component

public class MyWebSocket {

//当前连接数(注意:此处是非线程安全的)

private static int count = 0;

//使用线程安全的方式存放每个客户端对应的MyWebSocket对象

private static CopyOnWriteArraySet<MyWebSocket> webSocketSet = new

CopyOnWriteArraySet<MyWebSocket>();

//与客户端的连接会话

private Session session;

/**

* 连接建立成功调用的方法

*/

@OnOpen

public void onOpen(Session session) {

this.session = session;

webSocketSet.add(this); //加入set中

addOnlineCount(); //在线数加1

try {

sendMessage("当前在线人数为" + getOnlineCount());

} catch (IOException e) {

e.printStackTrace();


System.out.println("IO异常");

}

}

/**

* 连接关闭调用的方法

*/

@OnClose

public void onClose() {

webSocketSet.remove(this); //从set中删除

subOnlineCount(); //在线数减1

System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());

}

/**

* 收到客户端消息后调用的方法

* @param message 客户端发送过来的消息*/

@OnMessage

public void onMessage(String message, Session session) {

System.out.println("来自客户端的消息:" + message);

//群发消息

for (MyWebSocket item : webSocketSet) {

try {

item.sendMessage(message);

} catch (IOException e) {

e.printStackTrace();

}

}

}

/**

* 发生错误时调用

@OnError

*/

public void onError(Session session, Throwable error) {

System.out.println("发生错误");

error.printStackTrace();

}

public void sendMessage(String message) throws IOException {

this.session.getBasicRemote().sendText(message);

//this.session.getAsyncRemote().sendText(message);

}

public static synchronized int getOnlineCount() {

return count;

}

public static synchronized void addOnlineCount() {

count++;

}

public static synchronized void subOnlineCount() {

count--;

}


html页面: index.ftl

}

<!DOCTYPE HTML>

<html>

<head>

<title>简单聊天室</title>

</head>

<body>

<div id="messageDiv" style="width: 600px;height: 400px;border: 1px solid

red"></div>

<input id="contentTxt" type="text" /><input type="button" onclick="send()"

value="发送"/>

<input type="button" onclick="closeWebSocket()" value="退出聊天室"/>

</body>

<script type="text/javascript">

var websocket = null;

//判断当前浏览器是否支持WebSocket

if('WebSocket' in window){

websocket = new WebSocket("ws://localhost:8080/websocket");

}

else{

alert('当前浏览器不支持websocket')

}

//连接错误回调

websocket.onerror = function(){

showMessage("连接错误");

};

//连接成功回调

websocket.onopen = function(event){

showMessage("欢迎进入聊天室");

}

//接收消息回调

websocket.onmessage = function(event){

showMessage(event.data);

}

//连接关闭的回调方法

websocket.onclose = function(){

showMessage("连接关闭");

}

//监听窗口关闭事件

// 窗口关闭时,需要关闭websocket连接

window.onbeforeunload = function(){

websocket.close();

}

//将消息显示在网页上

function showMessage(msg){


启动类:

二. 整合solr

2.1 回顾solr

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。

Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xml文档添加、删除、更新索引 。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。

Solr与Lucene的区别:

Lucene是一个开放源代码的全文检索引擎工具包,它不是一个完整的全文检索引擎,Lucene提供了完整的查询引擎和索引引擎,目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者以Lucene为基础构建全文检索引擎。

Solr的目标是打造一款企业级的搜索引擎系统,它是一个搜索引擎服务,可以独立运行,通过Solr可以非常快速的构建企业的搜索引擎,通过Solr也可以高效的完成站内搜索功能。

2.2 solr的安装和配置到tomcat中

document.getElementById('messageDiv').innerHTML += msg + '<br/>';

}

//关闭连接

function closeWebSocket(){

websocket.close();

}

//发送消息

function send(){

var msg = document.getElementById('contentTxt').value;

websocket.send(msg);

}

</script>

</html>

@Controller

@SpringBootApplication

public class DemoApplication {

@RequestMapping("/")

public String index(){

return "/index";

}

public static void main(String[] args) {

SpringApplication.run(DemoApplication.class, args);

}

}


2.3 安装中文分词器

使用IKAnalyzer中文分析器。

解压分词器压缩包

第一步:把ik-analyzer-solr5-5.x.jar添加到tomcat中的solr/WEB-INF/lib目录下。

第二步:复制IKAnalyzer的配置文件IKAnalyzer.cfg.xml和自定义词典ext.dic和停用词词典stopword.dic到tomcat中的solr/WEB-INF/classpath下。

第三步:在solrhome/collection1/conf/managed-schema.xml中添加一个自定义的fieldType,使用中文分析器。

第四步:定义field,指定field的type属性为text_ik

第五步:重启tomcat

步骤:

1. 解压缩后将solr5.5.5/server/solr-webapp中的webapp文件夹复制到tomcat的webapps目录下,

并改名为solr

2. 将solr5.5.5/server/lib/ext中的所有jar包复制到tomcat下的solr/WEB-INF/lib下;

在solr的工程的WEB-INF下创建classes目录,然后将

solr5.5.5\server\resources\log4j.properties也复制到刚刚创建的classes目录下;把solr-

5.5.5\dist的solr-dataimporthandler-5.5.5.jar和solr-dataimporthandler-extras-

5.5.5.jar也放到solr的\WEB-INF\lib

3. 将solr5.5.5/server中的solr文件夹复制到随便一个地方并改名为solrhome(此处我使用homework

目录)

4. 将solrhome中的configsets中的sample_techproducts_configs复制出来与solr.xml平级,并

删除掉configsets文件夹,将sample_techproducts_configs改名为collection1(此处

collection1为任意名称)

5. 在solrhome/conf中创建一个文件core.properties,在里面添加内容: name=collection1(此

处的collection1为上一步命名的名称)

6. 将tomcat中的solr文件夹中的web.xml打开,找到被注释掉的代码:

<!--

<env-entry>

<env-entry-name>solr/home</env-entry-name>

<env-entry-value>/put/your/solr/home/here</env-entry-value>

<env-entry-type>java.lang.String</env-entry-type>

</env-entry>

-->

将其注释去掉,并将路径改成自己的solrhome路径。

<!-- IKAnalyzer定义一个域类型,这个类型相当于数据库中表中列的类型,比如 int,varchar 等,

每种类型有不同的处理机制-->

<fieldType name="text_ik" class="solr.TextField">

<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>

</fieldType>

<!--IKAnalyzer Field 定义一个域,指定类型,和其他属性, 域就相当于表中的列,类型就相当于

列的类型-->

<field name="title_ik" type="text_ik" indexed="true" stored="true" />

<field name="content_ik" type="text_ik" indexed="true" stored="false"

multiValued="true"/>


2.4 设置业务字段

如果不使用Solr提供的Field可以针对具体的业务需要自定义一套Field,如下是商品信息Field:,此处可以使用自己的配置,这里仅做演示用

2.5 文档基本操作

2.5.1 添加单个文档


2.5.2 批量导入数据

使用dataimport插件批量导入数据。

第一步:把dataimport插件依赖的jar(dist 目录下)包添加到solrhome(collection1\lib)中,或者是 solr 的 web 项目 lib 中,并且复制数据库连接依赖包(前面已经添加过了)

第二步:将mysql的驱动包放入到solr 的 web 项目 lib 中

第三步:配置solrconfig.xml文件,添加一个requestHandler。

第四步:创建一个data-config.xml,保存到collection1\conf\目录下

<!--例如:product-->

<field name="product_name" type="text_ik" indexed="true" stored="true"/>

<field name="product_price" type="float" indexed="true" stored="true"/>

<field name="product_description" type="text_ik" indexed="true"

stored="false" />

<field name="product_keywords" type="text_ik" indexed="true"

stored="false" multiValued="true"/>

<copyField source="product_name" dest="product_keywords"/>

<copyField source="product_description" dest="product_keywords"/>

<requestHandler name="/dataimport"

class="org.apache.solr.handler.dataimport.DataImportHandler">

<lst name="defaults">

<!--执行数据导入的配置文件-->

<str name="config">data-config.xml</str>

</lst>

</requestHandler>

<?xml version="1.0" encoding="UTF-8" ?>

<dataConfig>

<!--配置数据库连接-->

<dataSource type="JdbcDataSource"

driver="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/solr"

user="root"


第四步:重启tomcat


第五步:点击"execute"按钮导入数据 到入数据前会先清空索引库,然后再导入。

2.5.3. 删除文档(注意需要提交)

删除索引格式如下:

1) 删除制定ID的索引

2) 删除查询到的索引数据

3) 删除所有索引数据

password="root"/>

<document>

<!--配置实体, 此处的配置就类似于 hibernate 的映射,主要是执行一条 sql 语句,然后将返回的列和

solr 中的域进行对应,这样查询完成后会自动将对应列的数据放到solr 的对应域中-->

<entity name="Product" query="SELECT pid,name,price,description FROM

products ">

<!--column 代表 sql 语句返回的列名字,如果有别名,代表别名, name 代表的是在 solr

中用于存放该数据的域名 也就是 field 名字

此处和上面3.7步骤的配置域对应,为了演示,此处和上面做自己的对应即可,不一定非得照着来,毕竟表的列越

多,写起来越麻烦

-->

<field column="pid" name="id"/>

<field column="name" name="product_name"/>

<field column="price" name="product_price"/>

<field column="description" name="product_description"/>

</entity>

</document>

</dataConfig>

<delete>

<id>8</id>

</delete>

<delete>

<query>product_catalog_name:幽默杂货</query>

</delete>


2.5.4. 查询索引

通过/select搜索索引,Solr制定一些参数完成不同需求的搜索:

2.5.4.1 q

查询字符串,必须的,如果查询所有使用:


2.5.4.2 fq

(filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如:


过滤查询价格从1到20的记录。

也可以在"q"查询条件中使用product_price:[1 TO 20],如下:


也可以使用"*"表示无限,例如:

20以上:product_price:[20 TO *]

20以下:product_price:[* TO 20]

2.5.4.3. sort

排序,格式:sort=+<desc|asc>[,+<desc|asc>]… 。示例:

按价格降序


2.5.4.4. start

分页显示使用,开始记录下标,从0开始

2.5.4.5. rows

指定返回结果最多有多少条记录,配合start来实现分页。


显示前10条。


<delete>

<query>*:*</query>

</delete>


2.5.4.6. fl

指定返回那些字段内容,用逗号或空格分隔多个。

显示商品图片、商品名称、商品价格

2.5.4.7. df

-指定一个搜索Field


也可以在SolrCore目录 中conf/solrconfig.xml文件中指定默认搜索Field,指定后就可以直接在"q"查询条件中输入关键字。


2.5.4.8. wt

(writer type)指定输出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我们,因为默认没有打开。

2.5.4.9. hl

-是否高亮 ,设置高亮Field,设置格式前缀和后缀。(注意,必须有查询条件才能高亮,即q中必须有条件,不能是* : *)


2.6 在springboot中操作solr

第一步:导入对应的包 pom.xml

第二步:添加配置 application.properties

第三步:编写相应的代码

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-solr</artifactId>

</dependency>

spring.data.solr.host=http://127.0.0.1:8080/solr/collection1

@Repository

public class ProductSolrDAO {

@Resource

private SolrClient client;


/**

* 新增/修改 索引

* 当 id 存在的时候, 此方法是修改, 则是新增

* @return

*/

@RequestMapping("add")

public String add() {

String uuid = UUID.randomUUID().toString().replaceAll("-", "");

try {

SolrInputDocument doc = new SolrInputDocument();

doc.setField("id", uuid);

doc.setField("product_name", "Oppo手机");

doc.setField("product_price", "3000");

// collection1为solrcore名称,可以直接设置在url中

client.add(doc);

// client.add("collection1", doc);

client.commit();

// client.commit("collection1");

return uuid;

} catch (Exception e) {

e.printStackTrace();

}

return "error";

}

/**

* 根据id删除索引

* @param id

* @return

*/

@RequestMapping("delete")

public String delete(String id) {

try {

client.deleteById("collection1",id);

client.commit("collection1");

return id;

} catch (Exception e) {

e.printStackTrace();

}

return "error";

}

/**

* 删除所有的索引

* @return

*/

@RequestMapping("deleteAll")

public String deleteAll(){

try {

client.deleteByQuery("collection1","*:*");

client.commit("collection1");

return "success";

} catch (Exception e) {

e.printStackTrace();

}


return "error";

}

/**

* 根据id查询索引

* @return

* @throws Exception

*/

@RequestMapping("getById")

public String getById() throws Exception {

SolrDocument document = client.getById("collection1", "1");

System.out.println(document);

return document.toString();

}

/**

* 综合查询

* @return

*/

@RequestMapping("search")

public Map<String, Map<String, List<String>>> search(){

try {

SolrQuery params = new SolrQuery();

//查询条件, 这里的 q 对应 下面图片标红的地方

params.set("q", "手机");

//过滤条件

params.set("fq", "product_price:[100 TO 100000]");

//排序

params.addSort("product_price", SolrQuery.ORDER.asc);

//分页

params.setStart(0);

params.setRows(20);

//默认域

params.set("df", "product_name");

//只查询指定域

params.set("fl", "id,product_name,product_price");

//高亮

//打开开关

params.setHighlight(true);

//指定高亮域

params.addHighlightField("product_name");

//设置前缀

params.setHighlightSimplePre("<span style='color:red'>");

//设置后缀

params.setHighlightSimplePost("</span>");

QueryResponse queryResponse = client.query(params);

SolrDocumentList results = queryResponse.getResults();

long numFound = results.getNumFound();


System.out.println(numFound);

//获取高亮显示的结果, 高亮显示的结果和查询结果是分开放的

Map<String, Map<String, List<String>>> highlight =

queryResponse.getHighlighting();

for (SolrDocument result : results) {

System.out.println(result.get("id"));

System.out.println(result.get("product_name"));

System.out.println(result.get("product_price"));

Map<String, List<String>> map = highlight.get(result.get("id"));

List<String> list = map.get("product_name");

System.out.println(list.get(0));

System.out.println("------------------");

System.out.println();

}

return highlight;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

}

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表