I am working with siglarR self host service,my problem is message size,i want to decrease size from 1kb to only 30bytes because i am working on stock market service which send data very frequently but message size is low,but signalR takes minimum message size is 1kb ,it takes huge network bandwidth.if you have any solution please tell me.
Message example like '123|234.52|568'
// Please find the updated code below :
application send message to server code
if (IsConnected)
{
try
{
if (Convert.ToBoolean(ConfigurationManager.AppSettings["IsJsonData"].ToString()))
{
var obj = new
{
id = SymbolId,
head = colName_no,
value = string.Format("{0:0.####}", Double.Parse(newValue))
};
_hub.Invoke("ServerAlert", SymbolId, JsonConvert.SerializeObject(obj));
}
else
{
_hub.Invoke("ServerAlert", SymbolId, data);
}
}
catch (Exception ex)
{
GenerateLog(ex.ToString() + " " + JsonConvert.SerializeObject(dtrow), "server hub");
}
}
##server side code##
public async void ServerAlert(string groupName, string message)
{
//await Clients.All.StockAlert(message);
//string Delimiter = ConfigurationManager.AppSettings["SplitMessage"].ToString();
Clients.Group(groupName).GroupStockAlert(message);
}
client side receive message code
objMainForm._hub.On("GroupStockAlert", (x) =>
{
try
{
objMainForm.LastPingDateTime = DateTime.Now;
string[] ChangeData = x.Split(new string[] { objMainForm.Delimeter }, StringSplitOptions.RemoveEmptyEntries);
DataRow[] row = objMainForm.dtOnlineData.Select("SymbolId='" + ChangeData[0] + "'");
int RowIndex = objMainForm.dtOnlineData.Rows.IndexOf(row[0]);
DataTable Dt_ColumnName = objMainForm.dtAllHeaders.Select("RowNo='" + ChangeData[1] + "'").CopyToDataTable();
string exceldata = "t!!" + ChangeData[0] + "!!" + Dt_ColumnName.Rows[0]["Header"].ToString() + "!!" + ChangeData[2];
if (this.InvokeRequired)
this.Invoke(new livedata(this.ProcessServerData), new object[] { RowIndex, Dt_ColumnName.Rows[0]["Header"], ChangeData[2], ChangeData[0] });
ChangeData = null;
row = null;
RowIndex = 0;
}
catch (Exception ex)
{
}
finally
{
GC.SuppressFinalize(this);
}
});
Thanks All
Related
This is a c# method that invokes SAP BAPI.
public Message ReleaseBapi(string orderNumber)
{
Message msg = new Message();
DataTable dt = new DataTable();
_ecc = ERPRfcDestination.InitialiseDestination();
try
{
IRfcFunction api = _ecc.Repository.CreateFunction("BAPI_PRODORD_RELEASE");
IRfcTable orderNumTable = api.GetTable("ORDERS");
orderNumTable.Insert();
IRfcStructure ItemData = orderNumTable.CurrentRow;
orderNumber = orderNumber.PadLeft(12,'0');
ItemData.SetValue("ORDER_NUMBER", orderNumber);
api.SetValue("ORDERS", orderNumTable);
BeginContext();
api.Invoke(_ecc);
//EndContext();
IRfcTable detReturnTable = api.GetTable("DETAIL_RETURN");//On this line I am getting RfcInvalidStateException
IRFCToDatatable convertToDT = new IRFCToDatatable();
dt = convertToDT.ToDataTable(detReturnTable, dt);
if (dt.Rows.Count > 0)
{
msg.Msg = "Order number " + orderNumber + " released";
msg.MsgType = "S";
}
else { RollbackAPI(); }
}
catch (Exception ex)
{
msg.MsgType = "D";
msg.Msg = ex.Message;
RollbackAPI();
}
finally
{
EndContext();
}
return msg;
}
I checked every other instances where similar line of code is written and on debugging I found that it works as expected. Above is the only place where I am getting this error although I was able to invoke the Rfc method.
I need to grab all messages in a chat. I use C# and the TLSharp library.
I authrized, got the token etc. successfully.
But when I'm trying to get the messages in a loop, I'm going to an infinite loop.
So the text with the results is never appeared in the textbox.
I'd like to know what I'm doing wrong and how to fix it. Thanks.
using TeleSharp.TL;
using TeleSharp.TL.Messages;
using TLSharp.Core;
//using other standard...
//code for authorization etc. is skipped
int VKFID = 1175259547; //ID of the chat
int offset = 0;
int n = 1;
StringBuilder sb = new StringBuilder();
TelegramClient client = new TelegramClient(<key>, <hash>);
TLUser user;
private DateTime ConvertFromUnixTimestamp(double timestamp)
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
return origin.AddSeconds(timestamp);
}
private async void button3_Click(object sender, EventArgs e)
{
sb.Append("#\tDate\tTime\tMID\tTUID\tText" + Environment.NewLine);
TLDialogsSlice dialogs = (TLDialogsSlice)await client.GetUserDialogsAsync();
TLChannel chat = dialogs.Chats.Where(c => c.GetType() == typeof(TLChannel)).Cast<TLChannel>().FirstOrDefault(c => c.Id == VKFID);
TLInputPeerChannel inputPeer = new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = (long)chat.AccessHash };
while (true)
{
try
{
TLChannelMessages res = await client.SendRequestAsync<TLChannelMessages>
(new TLRequestGetHistory() { Peer = inputPeer, Limit = 1000, AddOffset = offset, OffsetId = 0 });
var msgs = res.Messages;
if (res.Count > offset)
{
offset += msgs.Count;
foreach (TLAbsMessage msg in msgs)
{
if (msg is TLMessage)
{
TLMessage message = msg as TLMessage;
sb.Append(n.ToString() + "\t" +
ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("dd'.'MM'.'yyyy") + "\t" +
ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("HH':'mm':'ss") + "\t" +
message.Id + "\t" + message.FromId + "\t" + message.Message + Environment.NewLine);
}
if (msg is TLMessageService)
continue;
n++;
}
Thread.Sleep(22000); //to avoid TelegramFloodException
}
else
break;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
break;
}
finally
{
await Task.Delay(22000); //to avoid TelegramFloodException
}
}
textBox2.Text = sb.ToString();
MessageBox.Show("Done");
}
There is now the WTelegramClient library, using the latest Telegram Client API protocol (connecting as a user, not bot).
The library is very complete but also very simple to use. Follow the README on GitHub for an easy introduction.
Connecting, finding your chat and retrieving all the messages can be done like this:
using TL;
using System.Linq;
const int TargetChatId = 1175259547;
using var client = new WTelegram.Client(); // or Client(Environment.GetEnvironmentVariable)
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
InputPeer peer = chats.chats.First(chat => chat.ID == TargetChatId);
for (int offset = 0; ;)
{
var messagesBase = await client.Messages_GetHistory(peer, 0, default, offset, 1000, 0, 0, 0);
if (messagesBase is not Messages_ChannelMessages channelMessages) break;
foreach (var msgBase in channelMessages.messages)
if (msgBase is Message msg)
{
// process the message
}
offset += channelMessages.messages.Length;
if (offset >= channelMessages.count) break;
}
Could you try to refresh your textbox before Thead.Sleep(22000)?
textBox2.Text += sb.ToString();
Application.DoEvents();
Thread.Sleep(22000);
Other way of doing this could be using a BackgroundWorker in the same way as it is used managing a ProgressBar.
I have a window Service which converts the PDF file to html and it is running in 5 threads.
Each thread picks the record from database where status is 0.Once it picks the record from database we are making the status to 64 and making an entry in log file so that other thread should not pick the same record,after successful conversion we are making the status to 256 if any exception we are making the stratus to 128.
Some records are updated to 64 with out any entry in log and they are not even processed further.
Below is the Stored Procedure to pick the single record from database.
Create PROCEDURE [SGZ].[p_GetNextRequestForProcessing]
#InstanceId int
AS
BEGIN
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
set nocount on
Declare #RequestID bigint = null;
SET #RequestID= (
Select
TOP(1) RequestID
From
sgz.PDFTransformationQueue
Where
RequestStatusID=0
);
If (#RequestID is not null)
BEGIN
Begin Transaction;
Update
sgz.PDFTransformationQueue
SET
RequestStatusid=64,
ProcessedInstanceID =#InstanceId,
ProcessStartTime = getutcdate(),
ModifiedDate=getutcdate()
Where
RequestID=#RequestID and
RequestStatusid =0 and
ProcessedInstanceID is null;
if ##rowcount = 0
set #RequestID=null;
Commit Transaction;
END
Select
RQ.VersionNumber,RQ.RequestID, RP.Payload
From
SGZ.RequestPayload RP WITH (NOLOCK),
SGZ.PDFTransformationQueue RQ WITH (NOLOCK)
Where
RP.RequestId=RQ.RequestID AND
ProcessedInstanceID=#InstanceId AND
RequestStatusid =64 AND
RQ.RequestId = #RequestID;
END
And below is the window service code:-
protected override void OnStart(string[] args)
{
PDFTransAutoProcessManager pdfTransAutoProcessManager = new
PDFTransAutoProcessManager();
pdfTransAutoProcessManager.OnProcessStart();
}
And PDFTransAutoProcessManager class:-
private int _runningAsyncThread = 0;
private int _totalAsynThread = 5;
public void OnProcessStart()
{
_logMgr.Info("Process started # " + DateTime.Now);
mainThread = new Thread(new ThreadStart(StartAutoProcess));
mainThread.Priority = ThreadPriority.Highest;
mainThread.Start();
}
private void StartAutoProcess()
{
try
{
while (true)
{
if (_runningAsyncThread < _totalAsynThread)
{
Thread childThread = new Thread(() => ProcessAsync());
Interlocked.Increment(ref _runningAsyncThread);
childThread.Start();
}
Thread.Sleep(100);
}
}
catch (Exception ex)
{ }
}
private void ProcessAsync()
{
try
{
PDFGenieManager pdfGenieManager = new
PDFGenieManager(_logMgr,gmi);
pdfGenieManager.ProcessRawData();
}
catch (Exception ex)
{
_logMgr.Info(ex.Message);
_logMgr.Info(ex.StackTrace);
}
finally
{
Interlocked.Decrement(ref _runningAsyncThread);
}
}
And in PDFGenieManager Class actual database call and conversion will happen.
When it is trying to get records from database some records are updated to 64 with out any entry in log.
Is it related to threading pattern or any problem with stored procedure.
Kindly help thanks in advance.
Below is the PDFGenieManager class code:-
namespace PDFConvertion
{
public class PDFGenieManager
{
public Logger _logMgr;
public GmiManager _gmi;
string _environment;
static readonly object _object = new object();
Dictionary<string, string> _ResourceMetadata = new Dictionary<string, string>();
public PDFGenieManager(Logger logMgr, GmiManager gmi)
{
_logMgr = logMgr;
_gmi = gmi;
_environment = ConfigurationManager.AppSettings["Envoirnment"];
}
public void ProcessRawData()
{
try
{
string unlockKey = string.Empty;
string languageRepair = string.Empty;
bool IsUnicodeRepair = false;
double confidenceScore = 1.0;
var Vendor = string.Empty;
string hiddenText = string.Empty;
DataTable rawData = new DataTable();
RuntimeCacheMgr _runtimeCacheMgr = new RuntimeCacheMgr();
DAL dal = new DAL();
try
{
rawData = dal.GetRawData();
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Info("Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
if (!_runtimeCacheMgr.Exists(_environment))
{
_ResourceMetadata = dal.getResourcemetaDataValue(_environment);
_runtimeCacheMgr.Add(_environment, _ResourceMetadata);
}
else
{
_ResourceMetadata = _runtimeCacheMgr.Get<Dictionary<string, string>>(_environment);
}
}
catch (SqlException exe)
{
_logMgr.Error("Sql Database Error While Picking the records from database" + exe.Message + exe.StackTrace, exe.InnerException);
}
catch (Exception ex)
{
if (ex != null && !ex.ToString().ToLower().Contains("already exist"))
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Error("Exception block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
_logMgr.Error("Exception block" + ex.Message);
return;
}
else
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Error("Cache block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
_logMgr.Error("Cache block" + ex.Message + "" + ex.StackTrace);
}
}
finally
{
if (rawData != null && rawData.Rows.Count > 0)
{
_logMgr.Info("Finally block Picked the record from datbase" + rawData.Rows[0]["Payload"].ToString());
}
}
List<PDFGenieTran> ids = new List<PDFGenieTran>(rawData.Rows.Count);
rawData.AsEnumerable().ToList().ForEach(row => ids.Add(new PDFGenieTran() { Payload = row["Payload"].ToString(), RequestID = Convert.ToInt64(row["RequestID"]), VersionNumber = row["VersionNumber"].ToString() }));
PDFNetStatus PDFstatus = new PDFNetStatus();
foreach (PDFGenieTran pdf in ids)
{
}
I want read all messages in my gmail account using c# and gmail api.
Can I do this?
I read a lot of articles in Gmail API, but i couldn't read messages.
Also I want to read a body of messages or header.
I will be very glad if someone can help me :)
I use this code snippet:
public static List<Message> ListMessages(GmailService service, String userId)
{
List<Message> result = new List<Message>();
UsersResource.MessagesResource.ListRequest request = service.Users.Messages.List(userId);
do
{
try
{
ListMessagesResponse response = request.Execute();
result.AddRange(response.Messages);
request.PageToken = response.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(request.PageToken));
return result;
}
And this:
foreach (var item in ListMessages(service,"me"))
MessageBox.Show(item.Snippet);
But in a result I have empty message box.
It works for me
var inboxlistRequest = service.Users.Messages.List("your-email-address");
inboxlistRequest.LabelIds = "INBOX";
inboxlistRequest.IncludeSpamTrash = false;
//get our emails
var emailListResponse = inboxlistRequest.Execute();
foreach (var mail in emailListResponse.Messages)
{
var mailId = mail.Id;
var threadId = mail.ThreadId;
Message message = service.Users.Messages.Get("your-email-address", mailId).Execute();
Console.WriteLine(message.Snippet);
}
Yes you should have no issue doing what you say. I would suggest reading the documentation a bit more.
First you have to authenticate - the following shows how to do this with a service account (more details here https://developers.google.com/gmail/api/auth/web-server)
serviceAccountEmail = primaryLink.serviceEmailAddress;
certificate = new X509Certificate2(AppDomain.CurrentDomain.BaseDirectory + "certs//" + primaryLink.certificate, primaryLink.certificatePassword, X509KeyStorageFlags.Exportable);
try
{
credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
User = z.us.emailAccount,
Scopes = new[] { "https://www.googleapis.com/auth/userinfo.email", "https://www.googleapis.com/auth/userinfo.profile", "https://mail.google.com/" }
}.FromCertificate(certificate));
if (credential.RequestAccessTokenAsync(CancellationToken.None).Result)
{
gs = new GmailService(
new Google.Apis.Services.BaseClientService.Initializer()
{
ApplicationName = "Example",
HttpClientInitializer = credential
});
}
else
{
throw new Exception("gmail authentication Error.");
}
}
catch (Exception ex)
{
throw ex;
}
ListMessagesResponse respM = reqM.Execute();
if (respM.Messages != null)
{
foreach (Message m in respM.Messages)
{}
}
Once you have the message List you can iterate through the messages and either use a MIME parser or traverse the message structure to get the header, body etc.
There are lots of posts in this forum which go through how to do that.
I searched for a full example, without luck, but this is my working example. Based on https://developers.google.com/gmail/api/guides
Authenticate : https://developers.google.com/gmail/api/auth/web-server
get ALL emails
loop through all emails by Id, and request message etc.
here is the code snippet to get the first email's atachments, but you can simply loop over all foundIds to get all emails, and use message.snippet to get body :
List<string> foundIds = new List<string>();
string outputDir = "/EXAMPLE/EXAMPLE/"; // your preferred Dir to save attachments to
List<Google.Apis.Gmail.v1.Data.Thread> resultThread = new List<Google.Apis.Gmail.v1.Data.Thread>();
UsersResource.ThreadsResource.ListRequest requestThread = service.Users.Threads.List("me");
do
{
try
{
ListThreadsResponse responseThread = requestThread.Execute();
resultThread.AddRange(responseThread.Threads);
foreach (var item in responseThread.Threads )
{
foundIds.Add(item.Id);
}
requestThread.PageToken = responseThread.NextPageToken;
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
} while (!String.IsNullOrEmpty(requestThread.PageToken));
try
{
Message message = service.Users.Messages.Get("me", foundIds[0]).Execute();
IList<MessagePart> parts = message.Payload.Parts;
foreach (MessagePart part in parts)
{
if (!String.IsNullOrEmpty(part.Filename))
{
String attId = part.Body.AttachmentId;
MessagePartBody attachPart = service.Users.Messages.Attachments.Get("me", foundIds[0], attId).Execute();
// Converting from RFC 4648 base64 to base64url encoding
// see http://en.wikipedia.org/wiki/Base64#Implementations_and_history
String attachData = attachPart.Data.Replace('-', '+');
attachData = attachData.Replace('_', '/');
byte[] data = Convert.FromBase64String(attachData);
File.WriteAllBytes(Path.Combine(outputDir, part.Filename), data);
}
}
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
I would suggest taking a look at this article on how to handle the actual response structure. It can be somewhat complex with the way the Gmail API gives the results back to you.
https://sigparser.com/developers/email-parsing/gmail-api/
#BlackCat, Your ListMessages looks good. Now, to get the message body, you have to decode MimeType "text/plain" or "text/html". For eg:
public static void GetBody(GmailService service, String userId, String messageId, String outputDir)
{
try
{
Message message = service.Users.Messages.Get(userId, messageId).Execute();
Console.WriteLine(message.InternalDate);
if (message.Payload.MimeType == "text/plain")
{
byte[] data = FromBase64ForUrlString(message.Payload.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
else
{
IList<MessagePart> parts = message.Payload.Parts;
if (parts != null && parts.Count > 0)
{
foreach (MessagePart part in parts)
{
if (part.MimeType == "text/html")
{
byte[] data = FromBase64ForUrlString(part.Body.Data);
string decodedString = Encoding.UTF8.GetString(data);
Console.WriteLine(decodedString);
}
}
}
}
Console.WriteLine("----");
}
catch (Exception e)
{
Console.WriteLine("An error occurred: " + e.Message);
}
}
Q:
When I use the transactions ,I'll get the following error on about 1 out of every 100 record.
This IfxTransaction has completed; it
is no longer usable
I can't expect when the error happen or what is the reason of this error.
I try to insert about 607 record in the same transaction.
My code:
public static int InsertGroups(List<Group> groups)
{
DBConnectionForInformix con = new DBConnectionForInformix("");
con.Open_Connection();
con.Begin_Transaction();
int affectedRow = -1;
Dictionary<string, string> groupsParameter = new Dictionary<string, string>();
try
{
foreach (Group a in groups)
{
groupsParameter.Add("id", a.GroupId.ToString());
groupsParameter.Add("name", a.Name);
groupsParameter.Add("studentcount", a.StudentCount.ToString());
groupsParameter.Add("divisiontag", a.DivisionTag.ToString());
groupsParameter.Add("entireclass", a.EntireClass.ToString());
groupsParameter.Add("classid", a.ClassId.ToString());
groupsParameter.Add("depcode", a.DepCode.ToString());
groupsParameter.Add("studycode", a.StudyCode.ToString());
groupsParameter.Add("batchnum", a.BatchNum.ToString());
affectedRow = DBUtilities.InsertEntityWithTrans("groups", groupsParameter, con);
groupsParameter.Clear();
if (affectedRow < 0)
{
break;
}
}
if (affectedRow > 0)
{
con.current_trans.Commit();
}
}
catch (Exception ee)
{
string message = ee.Message;
}
con.Close_Connection();
return affectedRow;
}
public void Begin_Transaction()
{
if (this.connection.State == ConnectionState.Open)
{
this.current_trans = this.connection.BeginTransaction(IsolationLevel.Serializable);
}
}
public static int InsertEntityWithTrans(string tblName, Dictionary<string, string> dtParams, DBConnectionForInformix current_conn)
{
int Result = -1;
string[] field_names = new string[dtParams.Count];
dtParams.Keys.CopyTo(field_names, 0);
string[] field_values = new string[dtParams.Count];
string[] field_valuesParam = new string[dtParams.Count];
dtParams.Values.CopyTo(field_values, 0);
for (int i = 0; i < field_names.Length; i++)
{
field_valuesParam[i] = "?";
}
//----------------------------------------------------------------------------------------------------------------------------------------------
string insertCmd = #"INSERT INTO " + tblName + " (" + string.Join(",", field_names) + ") values (" + string.Join(",", field_valuesParam) + ")";
//----------------------------------------------------------------------------------------------------------------------------------------------
IfxCommand com = new IfxCommand(insertCmd);
for (int j = 0; j < field_names.Length; j++)
{
com.Parameters.Add("?", field_values[j]);
}
try
{
Result = current_conn.Execute_NonQueryWithTransaction(com);
if (current_conn.connectionState == ConnectionState.Open && Result > 0)//OK: logging
{
# region // Log Area
#endregion
}
}
catch (Exception ex)
{
throw;
}
return Result;
}
public int Execute_NonQueryWithTransaction(IfxCommand com)
{
string return_msg = "";
int return_val = -1;
Open_Connection();
com.Connection = this.connection;
com.Transaction = current_trans;
try
{
return_val = com.ExecuteNonQuery();
}
catch (IfxException ifxEx)// Handle IBM.data.informix : mostly catched
{
return_val = ifxEx.Errors[0].NativeError;
return_msg = return_val.ToString();
}
catch (Exception ex)// Handle all other exceptions.
{
return_msg = ex.Message;
}
finally
{
if (!string.IsNullOrEmpty(return_msg))//catch error
{
//rollback
current_trans.Rollback();
Close_Connection();
connectionstate = ConnectionState.Closed;
}
}
return return_val;
}
You seem to be handling errors and rolling back the transaction in two places (in Execute_NonQueryWithTransaction and in InsertGroups.
And the return from Execute_NonQueryWithTransaction is used both to return error codes and to return rows affected. But in InsertGroups it is checked purely as a rows affected.
Could you have an error code from Execute_NonQueryWithTransaction (so transaction rolled back) being treated as success (rows inserted) in InsertGroups and the commit then fails?
Overall the code needs significant cleanup:
A catch block to only throw is pointless and just adds noise.
Just use exceptions for error handling, all normal returns should indicate success.