第一步:后台上传
package com.lpy.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.n3r.idworker.Sid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lpy.enums.BGMOperatorTypeEnum;
import com.lpy.mapper.BgmMapper;
import com.lpy.pojo.Bgm;
import com.lpy.pojo.BgmExample;
import com.lpy.service.VideoService;
import com.lpy.web.util.ZookeeperCurator;
import com.lpy.utils.JsonUtils;
import com.lpy.utils.PagedResult;
@Service
public class VideoServiceImpl implements VideoService {
@Autowired
private BgmMapper bgmMapper;
@Autowired
private Sid sid;
@Autowired
private ZookeeperCurator zookeeperCurator;
@Override
public void addBgm(Bgm bgm) { //和配置里面有切面行为 事务的配置
String bgmId=sid.nextShort();
bgm.setId(bgmId);
bgmMapper.insert(bgm);
Map<String, String> map=new HashMap<>();
map.put("operType", BGMOperatorTypeEnum.ADD.type);
map.put("path", bgm.getPath());
zookeeperCurator.sendBgmOperator(bgmId,JsonUtils.objectToJson(map));
}
@Override
public PagedResult queryBgmList(Integer page, Integer pageSize) {
//第一步:开始分页
PageHelper.startPage(page,pageSize);
//第二步:查询的条件
BgmExample example=new BgmExample();
//第三步:查询数据库的数据list
List<Bgm> list = bgmMapper.selectByExample(example);
//第四步:将查询出来的数据进行封装
PageInfo<Bgm> pageList=new PageInfo<>(list);
//第五步:将封装好的数据给我们自己写的帮助类里面,并返回
PagedResult result=new PagedResult();
result.setTotal(pageList.getPages());//总的页数
result.setRows(list);//每一列
result.setPage(page);//当前的页数
result.setRecords(pageList.getTotal());//总的数量
return result;
}
@Override
public void deleteBgm(String id) {
Bgm bgm = bgmMapper.selectByPrimaryKey(id);
bgmMapper.deleteByPrimaryKey(id);
Map<String, String> map=new HashMap<>();
map.put("operType", BGMOperatorTypeEnum.DELETE.type);
map.put("path", bgm.getPath());
zookeeperCurator.sendBgmOperator(id, JsonUtils.objectToJson(map));
}
}
第二步:在zookeeper curator创建子节点
package com.lpy.web.util;
import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class ZookeeperCurator {
//zookeeper客户端
private CuratorFramework client =null;
//日志(中间件的工具类都需要添加日志)
final static Logger log=LoggerFactory.getLogger(ZookeeperCurator.class);
//初始化 参数的client是在applicationContext-zookeeper.xml容器里面,通过配置进行赋值的
public ZookeeperCurator(CuratorFramework client) {
this.client=client;
}
//初始化
public void init() {
//设置命名空间
client = client.usingNamespace("admin");
try {
//判断在admin命名空间下是否有bgm节点 /admin/bgm
if(client.checkExists().forPath("/bgm")==null) {
/**
* 对于zookeeper来讲,有2种类型的节点
* 持久节点:当你创建一个节点的时候,这个节点就永远存在了,除非你手动删除
* 临时节点:创建一个节点之后,会话断开,会自动删除,当然也可以手动删除
*/
//函数式编程
client.create().creatingParentsIfNeeded() //创建节点
.withMode(CreateMode.PERSISTENT) //节点类型:持久节点
.withACL(Ids.OPEN_ACL_UNSAFE) //acl:匿名权限
.forPath("/bgm");
log.info("zookeeper初始化成功");
log.info("zookeeper服务器状态:{0}",client.isStarted());
}
} catch (Exception e) {
log.error("zookeeper客户端连接、初始化错误");
e.printStackTrace();
}
}
/**
* 增加或者删除bgm,向zookeeper-server创建子节点,供小程序后端监听
* @param bgmId
* @param operType
*/
public void sendBgmOperator(String bgmId,String operObj) {
try {
client.create().creatingParentsIfNeeded() //创建节点
.withMode(CreateMode.PERSISTENT) //节点类型:持久节点
.withACL(Ids.OPEN_ACL_UNSAFE) //acl:匿名权限
.forPath("/bgm"+bgmId,operObj.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
}
第三步:小程序端(消费端)实现增加和删除
package com.lpy;
import java.io.File;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.lpy.enums.BGMOperatorTypeEnum;
import com.lpy.service.BgmService;
import com.lpy.utils.JsonUtils;
//需要springboot去扫描, springboot是通过java类来进行配置的
@Component
public class ZookeeperCuratorClient {
//zookeeper客户端
private CuratorFramework client =null;
//日志(中间件的工具类都需要添加日志)
final static Logger log=LoggerFactory.getLogger(ZookeeperCuratorClient.class);
@Autowired
private BgmService bgmService;
public static final String ZOOKEEPER_SERVER="192.168.4.245:2181";
public void init() {
if(client!=null) {
return;
}
//第一步:创建重试策略
RetryPolicy retryPolicy=new ExponentialBackoffRetry(1000,5);
//第二步:创建zookeeper客户端
client=CuratorFrameworkFactory.builder().connectString(ZOOKEEPER_SERVER)
.sessionTimeoutMs(10000)
.retryPolicy(retryPolicy)
.namespace("admin").build();
//第三步:启动客户端
client.start();
//测试
try {
// String testNodeData = new String(client.getData().forPath("/bgm/..."));
// log.info("测试的节点数据为:{}",testNodeData);
addChildWatch("/bgm");//对bgm下面所有的子节点进行监听
} catch (Exception e) {
e.printStackTrace();
}
}
public void addChildWatch(String nodePath) throws Exception {
final PathChildrenCache cache=new PathChildrenCache(client, nodePath, true);
cache.start();
//添加监听器
cache.getListenable().addListener(new PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) throws Exception {
//做相应的事件处理
if(event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)) {
log.info("监听到事件CHILD_ADDED");
//第一步:从数据库查询bgm对象,获取路径path
String path = event.getData().getPath();//发生的事件对应的路径,节点最后有bgmId
String operatorObjStr =new String(event.getData().getData());//获取到操作类型
Map<String, String> map=JsonUtils.jsonToPojo(operatorObjStr, Map.class);
String operatorType=map.get("operType");
String songPath=map.get("path");
// String arr[]=path.split("/");
// String bgmId=arr[arr.length-1];
// Bgm bgm=bgmService.queryBgmById(bgmId);
//
// if(bgm==null) {
// return;
// }
//bgm所在的相对路径
// String songPath=bgm.getPath();
//第二步:定义保存到本地的bgm路径
String filePath="D:\\java_all\\workspace-wxxcs\\video-space"+songPath;
//第三步:定义下载的路径(播放的url)
String arrPath[]=songPath.split("\\\\");
String finalPath="";
//处理url的斜杠以及编码
for(int i=0;i<arrPath.length;i++) {
if(StringUtils.isNoneBlank(arrPath[i])) {
finalPath+="/";
finalPath+=URLEncoder.encode(arrPath[i], "UTF-8") ;
}
}
String bgmUrl="http://192.168.4.245:8080/mvc"+finalPath;
if(operatorType.equals(BGMOperatorTypeEnum.ADD.type)) {//添加
//下载bgm到springboot服务器
URL url=new URL(bgmUrl);
File file=new File(filePath);
//进行下载
FileUtils.copyURLToFile(url, file);
client.delete().forPath(path);
}else if(operatorType.equals(BGMOperatorTypeEnum.DELETE.type)) {//删除
File file=new File(filePath);
FileUtils.forceDelete(file);
client.delete().forPath(path);
}
}
}
});
}
}