PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Как мога да слушам postgresql база данни с SignalR Core в .net core проект?

Този пример е work asp.net core 3.0+. Пълният код е по-долу.

Стъпка 1. Създайте тригер на PostgreSql за действия за слушане

 create trigger any_after_alarm_speed after
 insert
 or
 delete
 or
 update
 on
 public.alarm_speed for each row execute procedure alarm_speedf();

Стъпка 2. Създайте процедура на Postgresql

CREATE OR REPLACE FUNCTION public.alarm_speedf()
RETURNS trigger
LANGUAGE plpgsql
AS $function$
BEGIN
IF TG_OP = 'INSERT' then
PERFORM pg_notify('notifyalarmspeed', format('INSERT %s %s', NEW.alarm_speed_id, 
NEW.alarm_speed_date));
ELSIF TG_OP = 'UPDATE' then
PERFORM pg_notify('notifyalarmspeed', format('UPDATE %s %s', OLD.alarm_speed_id, 
OLD.alarm_speed_date));
ELSIF TG_OP = 'DELETE' then
PERFORM pg_notify('notifyalarmspeed', format('DELETE %s %s', OLD.alarm_speed_id, 
OLD.alarm_speed_date));
END IF;
RETURN NULL;
END;
$function$;

Стъпка 3. Създайте хъб

  public class speedalarmhub : Hub
    {

        private IMemoryCache _cache;
       `private IHubContext<speedalarmhub> _hubContext;
         public speedalarmhub(IMemoryCache cache, IHubContext<speedalarmhub> hubContext)
        {
            _cache = cache;
            _hubContext = hubContext; 
        }

        public async Task SendMessage()
        {
            if (!_cache.TryGetValue("SpeedAlarm", out string response))
            {
                SpeedListener speedlist = new SpeedListener(_hubContext,_cache);
                speedlist.ListenForAlarmNotifications();
                string jsonspeedalarm = speedlist.GetAlarmList();
                _cache.Set("SpeedAlarm", jsonspeedalarm);
                await Clients.All.SendAsync("ReceiveMessage", _cache.Get("SpeedAlarm").ToString());
            }
            else
            {
                await Clients.All.SendAsync("ReceiveMessage", _cache.Get("SpeedAlarm").ToString());
            }
        }

    }

Стъпка 4. Създайте контролер на слушател

 public class SpeedListener :Controller
{
    private IHubContext<speedalarmhub> _hubContext;
    private IMemoryCache _cache;
    public SpeedListener(IHubContext<speedalarmhub> hubContext,IMemoryCache cache)
    {
        _hubContext = hubContext;
        _cache = cache; 
    }
    static string GetConnectionString()
    {
        var csb = new NpgsqlConnectionStringBuilder
        {
            Host = "yourip",
            Database = "yourdatabase",
            Username = "yourusername",
            Password = "yourpassword",
            Port = 5432,
            KeepAlive = 30
        };
        return csb.ConnectionString;
    }
    public void ListenForAlarmNotifications()
    {
        NpgsqlConnection conn = new NpgsqlConnection(GetConnectionString());
        conn.StateChange += conn_StateChange;
        conn.Open();
        var listenCommand = conn.CreateCommand();
        listenCommand.CommandText = $"listen notifyalarmspeed;";
        listenCommand.ExecuteNonQuery();
        conn.Notification += PostgresNotificationReceived;
        _hubContext.Clients.All.SendAsync(this.GetAlarmList());
        while (true)
        {
            conn.Wait();
        }
    }
    private void PostgresNotificationReceived(object sender, NpgsqlNotificationEventArgs e)
    {

        string actionName = e.Payload.ToString();
        string actionType = "";
        if (actionName.Contains("DELETE"))
        {
            actionType = "Delete";
        }
        if (actionName.Contains("UPDATE"))
        {
            actionType = "Update";
        }
        if (actionName.Contains("INSERT"))
        {
            actionType = "Insert";
        }
        _hubContext.Clients.All.SendAsync("ReceiveMessage", this.GetAlarmList());
    }
    public string GetAlarmList()
    {
        var AlarmList = new List<AlarmSpeedViewModel>();
        using (NpgsqlCommand sqlCmd = new NpgsqlCommand())
        {
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.CommandText = "sp_alarm_speed_process_get";
            NpgsqlConnection conn = new NpgsqlConnection(GetConnectionString());
            conn.Open();
            sqlCmd.Connection = conn;
            using (NpgsqlDataReader reader = sqlCmd.ExecuteReader())
            {
                while (reader.Read())
                {
                    AlarmSpeedViewModel model = new AlarmSpeedViewModel();
                    model.alarm_speed_id = reader.GetInt32(0);
                  // you must fill  your model items
                    AlarmList.Add(model);
                }
                reader.Close();
                conn.Close();
            }



        }
        _cache.Set("SpeedAlarm", SerializeObjectToJson(AlarmList));
        return _cache.Get("SpeedAlarm").ToString();
    }
    public String SerializeObjectToJson(Object alarmspeed)
    {
        try
        {
            var jss = new JavaScriptSerializer();
            return  jss.Serialize(alarmspeed);
        }
        catch (Exception) { return null; }
    }
    private void conn_StateChange(object sender, System.Data.StateChangeEventArgs e)
    {

        _hubContext.Clients.All.SendAsync("Current State: " + e.CurrentState.ToString() + " Original State: " + e.OriginalState.ToString(), "connection state changed");
    }
}

Стъпка 5 Извикване на център

<script src="~/lib/signalr.js"></script>

<script type="text/javascript">
// Start the connection.
var connection = new signalR.HubConnectionBuilder()
    .withUrl('/speedalarmhub')
    .build();


connection.on('ReceiveMessage', function (message) {

            var encodedMsg = message;
            // Add the message to the page.

});
// Transport fallback functionality is now built into start.
connection.start()
    .then(function () {

        console.log('connection started');
        connection.invoke('SendMessage');
    })
    .catch(error => {
        console.error(error.message);
    });

Стъпка 6. Добавете по-долу услуги за конфигуриране на кода при стартиране

public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews();
        services.AddSignalR();
        services.AddMemoryCache();
    }

Стъпка 7. добавете кода по-долу в метода за конфигуриране

app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
              endpoints.MapHub<speedalarmhub>("/speedalarmhub");
        });


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Колоната 'mary' не съществува

  2. Как да регистрирате заявки в PostgreSQL

  3. Как да стартирате приложението на python и postgres в един докер контейнер?

  4. Масив с множество типове данни в PostgreSQL

  5. Hibernate Postgresql изберете за актуализация с проблем с външно присъединяване