【问题标题】:How can i ping mysql clients?我如何 ping mysql 客户端?
【发布时间】:2021-10-24 10:34:52
【问题描述】:

如何创建服务器端脚本来 ping mysql 和 windows 窗体上的客户端以查看它们是否仍然登录? 例如 ping 一个客户端,他们必须做一些事情来验证他们是否仍然在线。

【问题讨论】:

  • Mysql 连接是持久的,所以如果客户端离线,它会终止连接。您还可以为空闲连接设置超时。
  • 对不起,我应该指定更多。因此,在我的 Windows 应用程序的登录屏幕上,我登录到 mysql 数据库中的一个用户表,我只是通过一个名为“islogged”的条目来记录它,当应用程序退出时,我更新该表 islogged =“NO”。但是,例如,如果用户在退出应用程序之前断开互联网连接,则该条目在 islogged = 'NO' 处重新出现,然后他们无法在稍后阶段重新登录,因为我在允许他们登录之前检查用户是否已登录跨度>
  • 如果您有一个两层应用程序(客户端 - 数据库),那么在不显着重写客户端的情况下,您将无能为力。如果你有一个三层的应用程序(客户端 - 应用程序服务器 - 数据库),那么你可以在应用程序服务器层中加入这个特性。

标签: c# php mysql .net


【解决方案1】:

您不能直接从服务器 ping 客户端,但有一些选项。

关于超时

我认为在任何情况下你都必须使用服务器端超时 (wait_timeout),这个超时可以设置在服务器范围内或在从客户端连接时设置,例如:

SET SESSION wait_timeout = 60

这是必需的,因为客户端可能会在没有关闭 tcp 连接的情况下突然消失,并且显式超时将有助于 mysql 在客户端不活动的 wait_timeout 秒后关闭连接并释放资源。根据mysql manual默认超时时间相当大:28800秒。

有一个缺点。如果在正常操作期间您的客户端可能处于非活动状态超过 wait_timeout 秒,那么客户端应该知道如何处理关闭的连接(当数据库告诉它已经消失时重新连接)或者它应该发送“ping”查询(如select 1)至少每wait_timeout - 1 秒一次。

使用 get_lock() 函数

自 mysql 5.7(以及自 10.0.2 以来的 mariadb)您可以使用多个 user-level locks

使用 GET_LOCK() 获得的锁通过执行 RELEASE_LOCK() 显式释放或在会话终止(正常或异常)时隐式释放。事务提交或回滚时不会释放使用 GET_LOCK() 获得的锁。

所以想法是在客户端连接时发出 get_lock 查询,例如:

SELECT GET_LOCK('logged_in_{CLIENT_ID}', timeout)

您可以将 timeout 设置为 0 并立即告诉客户端无法登录,或者您可以等待(阻塞)最多 wait_timeout 秒以确保确实有另一个客户端持有锁。

当客户端断开连接或等待超时后,服务器将自动释放此锁。 如果锁是免费的 get_lock() 将返回1 否则(等待超时秒后)将返回0

使用进程ID

如果不想使用锁,可以使用进程的PID。

当客户端连接而不是写入islogged = 'YES' 时,您可以使用当前的 CONNECTION_ID() 作为值。 在登录之前,您可以检查当前客户端没有像这样的活动进程

SELECT islogged FROM logged
INNER JOIN information_schema.processlist ON
    processlist.id = logged.islogged
WHERE
   client_id = ...

如果上面的查询没有返回任何内容,那么您可以将新的 pid 插入到已记录的表中

REPLACE INTO logged SET islogged = CONNECTION_ID(), client_id = ...

我更喜欢使用 get_lock(),因为它看起来更容易,不会遇到并发问题并且允许实现等待。

不要忘记超时是必不可少的,您必须处理重新连接或发送定期 ping 以避免客户端出现意外的“服务器已消失”问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多