- 浏览: 141540 次
- 性别:
- 来自: 青岛
-
最新评论
-
cloudfile:
谢谢分享
xmpp with openfire之五 插件-利用Broadcast实现群 -
feitianzi:
碰到这个问题了,我的web.xml 也不起作用
glassfish 重新加载web.xml的问题 -
moistrot:
将这个编译好的类,加入我的lib\openfire.jar,之 ...
xmpp with openfire之四 扩展的AuthProvider -
lookdd1:
hetylei 写道lookdd1 写道请问,整合现有数据库为 ...
xmpp with openfire之三 openfire扩展小试 整合现有系统用户 -
hetylei:
lookdd1 写道请问,整合现有数据库为oracle的时候如 ...
xmpp with openfire之三 openfire扩展小试 整合现有系统用户
上一篇中提到jdbcAuthProvider.passwordType提供了三种方式
如果你的密码加密规则不是这三种方式,可以自己进行扩充
首先,下载openfire的源码
http://www.igniterealtime.org/downloads/source.jsp
打开org.jivesoftware.openfire.auth.JDBCAuthProvider
看以看到通过读取PASSWORDTYPE配置
进行密码的验证
这样完全可以仿照JDBCAuthProvider重新构造
编译后将此class加入到lib/openfire.jar中即可
当然不要忘记 将系统属性中
provider.auth.className,改成你自已的Provider
*上述代码例子中是org.yxsoft.openfire.plugin.BFMPAuthProvider
jdbcAuthProvider.passwordType,改成你自己定义的枚举值
*上述代码例子中是bfmp
如果你的密码加密规则不是这三种方式,可以自己进行扩充
首先,下载openfire的源码
http://www.igniterealtime.org/downloads/source.jsp
打开org.jivesoftware.openfire.auth.JDBCAuthProvider
package org.jivesoftware.openfire.auth; import org.jivesoftware.database.DbConnectionManager; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.openfire.user.UserAlreadyExistsException; import org.jivesoftware.openfire.user.UserManager; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import java.sql.*; /** * The JDBC auth provider allows you to authenticate users against any database * that you can connect to with JDBC. It can be used along with the * {@link HybridAuthProvider hybrid} auth provider, so that you can also have * XMPP-only users that won't pollute your external data.<p> * * To enable this provider, set the following in the system properties: * <ul> * <li><tt>provider.auth.className = org.jivesoftware.openfire.auth.JDBCAuthProvider</tt></li> * </ul> * * You'll also need to set your JDBC driver, connection string, and SQL statements: * * <ul> * <li><tt>jdbcProvider.driver = com.mysql.jdbc.Driver</tt></li> * <li><tt>jdbcProvider.connectionString = jdbc:mysql://localhost/dbname?user=username&password=secret</tt></li> * <li><tt>jdbcAuthProvider.passwordSQL = SELECT password FROM user_account WHERE username=?</tt></li> * <li><tt>jdbcAuthProvider.passwordType = plain</tt></li> * <li><tt>jdbcAuthProvider.allowUpdate = true</tt></li> * <li><tt>jdbcAuthProvider.setPasswordSQL = UPDATE user_account SET password=? WHERE username=?</tt></li> * </ul> * * The passwordType setting tells Openfire how the password is stored. Setting the value * is optional (when not set, it defaults to "plain"). The valid values are:<ul> * <li>{@link PasswordType#plain plain} * <li>{@link PasswordType#md5 md5} * <li>{@link PasswordType#sha1 sha1} * </ul> * * @author David Snopek */ public class JDBCAuthProvider implements AuthProvider { private String connectionString; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * Constructs a new JDBC authentication provider. */ public JDBCAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.connectionString"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.connectionString"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); } } public void authenticate(String username, String password) throws UnauthorizedException { if (username == null || password == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. createUser(username); } public boolean isPlainSupported() { // If the auth SQL is defined, plain text authentication is supported. return (passwordSQL != null); } public boolean isDigestSupported() { // The auth SQL must be defined and the password type is supported. return (passwordSQL != null && passwordType == PasswordType.plain); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { if (allowUpdate && setPasswordSQL != null) { setPasswordValue(username, password); } else { throw new UnsupportedOperationException(); } } public boolean supportsPasswordRetrieval() { return (passwordSQL != null && passwordType == PasswordType.plain); } /** * Returns the value of the password field. It will be in plain text or hashed * format, depending on the password type. * * @param username user to retrieve the password field for * @return the password value. * @throws UserNotFoundException if the given user could not be loaded. */ private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } private void setPasswordValue(String username, String password) throws UserNotFoundException { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString); pstmt = con.prepareStatement(setPasswordSQL); pstmt.setString(1, username); if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } pstmt.setString(2, password); rs = pstmt.executeQuery(); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a hex-encoded MD5 hash. */ md5, /** * The password is stored as a hex-encoded SHA-1 hash. */ sha1; } /** * Checks to see if the user exists; if not, a new user is created. * * @param username the username. */ private static void createUser(String username) { // See if the user exists in the database. If not, automatically create them. UserManager userManager = UserManager.getInstance(); try { userManager.getUser(username); } catch (UserNotFoundException unfe) { try { Log.debug("JDBCAuthProvider: Automatically creating new user account for " + username); UserManager.getUserProvider().createUser(username, StringUtils.randomString(8), null, null); } catch (UserAlreadyExistsException uaee) { // Ignore. } } } }
看以看到通过读取PASSWORDTYPE配置
JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); 。。。。。 。。。。。 。。。。。 passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); } catch (IllegalArgumentException iae) { Log.error(iae); }
进行密码的验证
if (passwordType == PasswordType.md5) { password = StringUtils.hash(password, "MD5"); } else if (passwordType == PasswordType.sha1) { password = StringUtils.hash(password, "SHA-1"); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); }
这样完全可以仿照JDBCAuthProvider重新构造
package org.yxsoft.openfire.plugin; import org.jivesoftware.openfire.user.UserNotFoundException; import org.jivesoftware.openfire.auth.*; import org.jivesoftware.openfire.XMPPServer; import org.jivesoftware.util.JiveGlobals; import org.jivesoftware.util.Log; import org.jivesoftware.util.StringUtils; import org.jivesoftware.database.DbConnectionManager; import java.sql.*; import java.security.MessageDigest; /** * Created by cl * Date: 2008-9-4 * Time: 9:18:26 * 仿照JDBCAuthProvider * 在数据库连接上 支持user/password * 密码验证 使用bfmp的机制 */ public class BfmpAuthProvider implements AuthProvider { private String connectionString; private String user; private String password; private String passwordSQL; private String setPasswordSQL; private PasswordType passwordType; private boolean allowUpdate; /** * 初始化 * 比JDBCAuthProvider多支持 * JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); */ public BfmpAuthProvider() { // Convert XML based provider setup to Database based JiveGlobals.migrateProperty("jdbcProvider.driver"); JiveGlobals.migrateProperty("jdbcProvider.url"); JiveGlobals.migrateProperty("jdbcProvider.user"); JiveGlobals.migrateProperty("jdbcProvider.password"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); JiveGlobals.migrateProperty("jdbcAuthProvider.setPasswordSQL"); JiveGlobals.migrateProperty("jdbcAuthProvider.allowUpdate"); JiveGlobals.migrateProperty("jdbcAuthProvider.passwordType"); // Load the JDBC driver and connection string. String jdbcDriver = JiveGlobals.getProperty("jdbcProvider.driver"); try { Class.forName(jdbcDriver).newInstance(); } catch (Exception e) { Log.error("Unable to load JDBC driver: " + jdbcDriver, e); return; } connectionString = JiveGlobals.getProperty("jdbcProvider.url"); user = JiveGlobals.getProperty("jdbcProvider.user"); password = JiveGlobals.getProperty("jdbcProvider.password"); // Load SQL statements. passwordSQL = JiveGlobals.getProperty("jdbcAuthProvider.passwordSQL"); setPasswordSQL = JiveGlobals.getProperty("jdbcAuthProvider.setPasswordSQL"); allowUpdate = JiveGlobals.getBooleanProperty("jdbcAuthProvider.allowUpdate",false); passwordType = PasswordType.plain; try { passwordType = PasswordType.valueOf( JiveGlobals.getProperty("jdbcAuthProvider.passwordType", "plain")); Log.error("PasswordType:"+ passwordType); } catch (IllegalArgumentException iae) { Log.error(iae); } } public boolean isPlainSupported() { //default return true; } public boolean isDigestSupported() { //default return true; } public void authenticate(String username, String password) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (username == null || password == null) { throw new UnauthorizedException(); } Log.error(username+":"+password); username = username.trim().toLowerCase(); if (username.contains("@")) { Log.error(username+":"+XMPPServer.getInstance().getServerInfo().getXMPPDomain()); // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } else { Log.error("user name not contains "); } String userPassword; try { userPassword = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } // If the user's password doesn't match the password passed in, authentication // should fail. if (passwordType == PasswordType.bfmp) { //这里BfmpMD5 就是自己的密码规则 password = BfmpMD5(password); } if (!password.equals(userPassword)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public void authenticate(String username, String token, String digest) throws UnauthorizedException, ConnectionException, InternalUnauthenticatedException { if (passwordType != PasswordType.plain) { throw new UnsupportedOperationException("Digest authentication not supported for " + "password type " + passwordType); } if (username == null || token == null || digest == null) { throw new UnauthorizedException(); } username = username.trim().toLowerCase(); if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. Return authentication failed. throw new UnauthorizedException(); } } String password; try { password = getPasswordValue(username); } catch (UserNotFoundException unfe) { throw new UnauthorizedException(); } String anticipatedDigest = AuthFactory.createDigest(token, password); if (!digest.equalsIgnoreCase(anticipatedDigest)) { throw new UnauthorizedException(); } // Got this far, so the user must be authorized. //createUser(username); } public String getPassword(String username) throws UserNotFoundException, UnsupportedOperationException { if (!supportsPasswordRetrieval()) { throw new UnsupportedOperationException(); } if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } return getPasswordValue(username); } private String getPasswordValue(String username) throws UserNotFoundException { String password = null; Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; if (username.contains("@")) { // Check that the specified domain matches the server's domain int index = username.indexOf("@"); String domain = username.substring(index + 1); if (domain.equals(XMPPServer.getInstance().getServerInfo().getXMPPDomain())) { username = username.substring(0, index); } else { // Unknown domain. throw new UserNotFoundException(); } } try { con = DriverManager.getConnection(connectionString, user, this.password); pstmt = con.prepareStatement(passwordSQL); pstmt.setString(1, username); rs = pstmt.executeQuery(); // If the query had no results, the username and password // did not match a user record. Therefore, throw an exception. if (!rs.next()) { throw new UserNotFoundException(); } password = rs.getString(1); } catch (SQLException e) { Log.error("Exception in JDBCAuthProvider", e); throw new UserNotFoundException(); } finally { DbConnectionManager.closeConnection(rs, pstmt, con); } return password; } public void setPassword(String username, String password) throws UserNotFoundException, UnsupportedOperationException { // unsupport } public boolean supportsPasswordRetrieval() { return true; } /** * Indicates how the password is stored. */ @SuppressWarnings({"UnnecessarySemicolon"}) // Support for QDox Parser public enum PasswordType { /** * The password is stored as plain text. */ plain, /** * The password is stored as a bfmp passwrod. */ bfmp; } private String BfmpMD5 (String source) { //在这里实现你的加密机制,返回生成的密码 return ""; } }
编译后将此class加入到lib/openfire.jar中即可
当然不要忘记 将系统属性中
provider.auth.className,改成你自已的Provider
*上述代码例子中是org.yxsoft.openfire.plugin.BFMPAuthProvider
jdbcAuthProvider.passwordType,改成你自己定义的枚举值
*上述代码例子中是bfmp
发表评论
-
对不起,免费午餐现在只提供稀饭了-- MSN停止支持对第三方软件的登录请求
2009-01-14 12:36 1745MSN停止支持对第三方软件的登录请求在网络上引起一阵讨论。 ... -
WebQQ限量封测第二期开启
2009-01-14 11:01 1165刚才听说WebQQ限量封测第二期开启了 去申请了一下,还要通 ... -
推荐:iJab ajax jabber 客户端
2009-01-13 14:23 3771昨天在XMPP群里,iJab的成员自荐了一下他们的ajax j ... -
xmpp with openfire之五 插件-利用Broadcast实现群
2008-12-12 11:28 15324openfire提供了很好的插件支持,安装也非常方便。 下面 ... -
xmpp with openfire之三 openfire扩展小试 整合现有系统用户
2008-12-10 15:44 10856openfire服务器配置,先 ... -
xmpp with openfire之二 openfire安装
2008-12-10 13:14 6745windows下的安装 1.首先 ... -
xmpp with openfire之一 xmpp and openfire
2008-12-10 10:17 6473XMPP 百度百科 1、什么是XMPP ? XMP ...
相关推荐
先说一下为什么要写这篇博客,是因为本人在周末在研究XMPP和OpenFire,从网上下载了个Demo,但跑不起来,花了很长时间,经改造后,跑起来了,写个篇博文也是希望后边学习XMPP和OpenFire的同学下载后直接运行,少走...
Openfire的强大之处在于其高度可扩展的插件系统。通过安装插件,可以极大地增强服务器的功能。 ##### 3.1 KrakenIMGateway插件 - **功能**:支持MSNS、QQ等第三方即时通讯工具的登录。 - **配置**:通过插件配置...
XMPP的核心设计原则是分散式和可扩展性,使得开发者可以轻松地添加新功能。在多人聊天系统中,XMPP负责处理用户的登录、注销、消息传递、群组管理等核心功能。用户通过连接到XMPP服务器,发送和接收消息,建立和管理...
**XMPP与Openfire搭建详解** XMPP(Extensible Messaging and Presence Protocol)是一种基于XML的实时通讯协议,常用于构建即时通讯系统。它允许用户进行一对一、一对多的消息传输,同时还支持状态呈现、群组聊天...
c语言学习
人脸识别项目源码实战
人脸识别项目源码实战
本图书进销存管理系统管理员功能有个人中心,用户管理,图书类型管理,进货订单管理,商品退货管理,批销订单管理,图书信息管理,客户信息管理,供应商管理,库存分析管理,收入金额管理,应收金额管理,我的收藏管理。 用户功能有个人中心,图书类型管理,进货订单管理,商品退货管理,批销订单管理,图书信息管理,客户信息管理,供应商管理,库存分析管理,收入金额管理,应收金额管理。因而具有一定的实用性。 本站是一个B/S模式系统,采用Spring Boot框架,MYSQL数据库设计开发,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得图书进销存管理系统管理工作系统化、规范化。本系统的使用使管理人员从繁重的工作中解脱出来,实现无纸化办公,能够有效的提高图书进销存管理系统管理效率。 关键词:图书进销存管理系统;Spring Boot框架;MYSQL数据库
基于动态规划和模型预测控制的并联混合电动汽车最佳控制 简介:利用动态规划,使用模型预测控制,实现对并联混合动力电动汽车的最佳控制,并降低总体成本函数 使用动态规划可以实现混合动力电动汽车的优化控制 混合动力电动汽车的模型预测控制是通过使用动态规划在缩短的时域内实现的 代码为纯matlab脚本,附带说明电子文档 ,并联混合电动汽车; 动态规划; 模型预测控制; 最佳控制; 总体成本函数; Matlab脚本。,动态规划与模型预测控制在并联混合动力电动汽车的最优控制策略
人脸识别项目实战
2025 DeepSeek技术全景解析-重塑全球AI生态的中国力量.pdf
能够爬取非会员视频和音频资源,可通过ffmpeg等工具将视频资源和音频资源合并
基于差分进化算法DE的机器人路径规划 本产品基于优化的差分进化算法,专为机器人山地路径规划而设计 通过模拟差分进化过程中的变异、交叉与选择机制,算法能够智能探索并确定最优行进路线,全面考量路径长度、能量消耗及地形适应性 优化之处在于融合了动态差分权重与精英保留策略,显著增强了算法的搜索效率和求解质量,有效规避了早熟收敛的风险 该算法在山地这一复杂且多变的自然环境中展现出卓越性能,完美适配于机器人探险、山地救援、环境监测等多种应用场景 我们矢志为用户提供卓越、稳健的机器人路径规划方案,推动各类山地作业迈向更为精确与高效的路径规划新时代 ,差分进化算法DE; 机器人路径规划; 山地路径规划; 算法优化; 早熟收敛风险规避; 山地探险应用场景; 环境监测场景。,DE算法赋能机器人,优化山地路径规划方案
情侣游戏情侣飞行棋10元真心话大冒险情侣情趣骰子php源码 ----- 程序特色 ----- 1、完整的分销制度,可自定义多种不同的返佣比例 2、支持情侣飞行棋、情趣骰子,多种等级 3、无感微信自动授权登录,支持微信第三方授权登录 4、完全开源无加密
HeidiSQL的12.2.0.6576安装压缩包
监护人,小孩和玩具数据集 4647张原始图片 监护人 食物 孩子 玩具 精确率可达85.4% yolov5pytorch格式
本课程是 PHP 进阶系列之 Swoole 入门精讲,系统讲解 Swoole 在 PHP 高性能开发中的应用,涵盖 协程、异步编程、WebSocket、TCP/UDP 通信、任务投递、定时器等核心功能。通过理论解析和实战案例相结合,帮助开发者掌握 Swoole 的基本使用方法及其在高并发场景下的应用。 适用人群: 适合 有一定 PHP 基础的开发者、希望提升后端性能优化能力的工程师,以及 对高并发、异步编程感兴趣的学习者。 能学到什么: 掌握 Swoole 基础——理解 Swoole 的核心概念,如协程、异步编程、事件驱动等。 高并发处理——学习如何使用 Swoole 构建高并发的 Web 服务器、TCP/UDP 服务器。 实战项目经验——通过案例实践,掌握 Swoole 在 WebSocket、消息队列、微服务等场景的应用。 阅读建议: 建议先掌握 PHP 基础,了解 HTTP 服务器和并发处理相关概念。学习过程中,结合 官方文档和实际项目 进行实践,加深理解,逐步提升 Swoole 开发能力。
机器人先进视觉赛-基于深度学习yolov8的3D识别项目源码含gui界面(最新发布).zip 实现机器人的3D目标识别和分割功能 支持深度图像的处理和分析 【资源详情说明】 【1】该项目为近期精心打造开发,完整代码。同时,配套资料一应俱全,涵盖详细的设计文档 【2】项目上传前源码经过严格测试,在多种环境下均能稳定运行,功能完善且稳定运行,技术研究、教学演示还是项目实践,都能轻松复现,节省时间和精力。 【3】本项目面向计算机相关专业领域的各类人群,对于高校学生,可作为毕业设计、课程设计、日常作业的优质参考;对于科研工作者和行业从业者,可作为项目初期立项演示,助力快速搭建原型,验证思路。 【4】若具备一定技术基础,可在此代码上进行修改,以实现其他功能,也可直接用于毕设、课设、作业等。 【5】小白,在配置环境或运行项目时遇到困难,可提供远程指导和全方位技术支持。 欢迎下载学习本项目资源,期待与你共同探讨技术问题,交流项目经验!
Matlab实现TSO-XGBoost多变量回归预测 Matlab实现TSO-XGBoost多变量回归预测,金枪鱼算法优化XGBoost多变量回归预测 1.data为数据集,7个输入特征,1个输出特征 2.MainTSO XGboost.m为主程序文件,其他为函数文件,无需运行 3.命令窗口输出R2、MAE、MAE和RMSEP等评价指标,可在下载区获取数据和程序内容 注意程序和数据放在一个文件夹,文件夹不可以XGBoost命名,因为有函数已经用过,运行环境为 Matlab2018及以上,预测效果如下 ,TSO-XGBoost; 多变量回归预测; Matlab实现; 金枪鱼算法优化; 评价指标; 预测效果; 文件夹结构; 运行环境,Matlab中TSO-XGBoost多变量回归预测优化实践
实时音视频SRT协议中文完整版