网站首页 > 开源技术 正文
一. 整合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;
}
}
猜你喜欢
- 2024-10-23 ES 基本知识(es基本介绍)
- 2024-10-23 maven打包jar包时如何打包本地jar文件
- 2024-10-23 记录自己搭建solr配置中文分词的过程供大家参考
- 2024-10-23 ElasticSearch安装ik分词插件(elasticsearch 安装ik分词器)
- 2024-10-23 12K的码农怎样蜕变为30k的架构师?找准方向,拒绝迷茫
- 2024-10-23 Lucene就是这么简单(好儿子今天妈妈就是你的女人了)
- 2024-10-23 5分钟带你了解Lucene全文索引(lucene索引原理)
- 2024-10-23 在.net core中进行中文分词方法(.net core hangfire)
- 2024-10-23 Elasticsearch-通过外网访问加入kibana,head「002」
- 2024-10-23 SpringBoot+kafka+ELK分布式日志收集
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)