Я использую ASP .Net 3.5 MVC1 с бэкэнд DB2. Моя компания пытается распечатать штрих-коды из диалогового окна GDI + Microsoft SQL Server 2008 RSCLient Print. Мы не можем сохранять файлы в формате PDF и печатать локально, потому что это для нашего приложения физической инвентаризации, а партнеры могут делать плохие вещи с помощью локальных штрих-кодов (они являются хорошими проверками), поэтому мы вынуждены печатать по HTTP и контролировать их печать , Каждый магазин имеет сервер печати на месте, но веб-сервер находится в корпоративном ИТ-офисе. Я считаю, что мне нужно использовать .jpeg, потому что .gif заставит строки в штрих-коде размываться и не читаться сканирующим пистолетом.C# RSClientPrint ОЧЕНЬ большая катушка
Приложение прекрасно работает с несколькими сотнями тегов (около 5 страниц и около 5 минут для завершения печати), но для печати 2000 тегов требуется около 2 часов (около 300 страниц около +150 МБ). Я запустил Wireshark в приложении, чтобы попытаться поймать пакеты, возвращающиеся туда и обратно, и передал информацию в сети, и это был их ответ.
NO. Time Source Destination Protocol Info 36628 653,373235 HTTP [TCP Window Full] Продолжение или не HTTP трафик 36630 654,245430 TCP [TCP ZeroWindowProbe] HTTP> 35503 [ACK] Seq = 26291213 Ack = 3730 Win = 63137 Len = 1
Я отвлекаюсь на задний план. Мой вопрос в том, какой тип стратегии я могу использовать, чтобы ускорить работу очереди печати по HTTP. Должен ли я «расколоть» печатающую катушку на X-страницах и снова залить катушку? Должен ли я изменить свой алгоритм печати? Каким образом можно уменьшить размер моего печатающего устройства, не потеряв качество .jpeg? Есть ли и открытая или коммерческая альтернатива RSClientPrint, которая будет обрабатывать бизнес-логику, в которой я нуждаюсь?
Теперь для кодирования доброты! Если вам нужно что-нибудь еще, дайте мне знать!
[AcceptVerbs(HttpVerbs.Post)]
[Authorization(Roles = Roles.NonInquiry)]
public ActionResult ReprintLabels(int eventId, int areaCode, int lowerLabelNumber, int upperLabelNumber)
{
if (!_eventAreaService.IsAreaEditable(eventId, areaCode))
return RedirectToAction("Index", new { eventId = eventId });
var printContext = _eventAreaService.ReprintLabels(eventId, areaCode, lowerLabelNumber, upperLabelNumber);
ActionResult result = RedirectToAction("Index", new { eventId = eventId });
if (printContext != null)
{
var redirectUrl = Url.RouteUrl(new { controller = "EventArea", action = "Index", eventId = eventId });
Session[PrintContextViewModel.SessionKey] = new PrintContextViewModel(printContext, redirectUrl);
result = RedirectToAction("PrintLabels", "LabelPrint");
}
return result;
}
public InventoryAreaPrintContext ReprintLabels(int eventId, int areaCode, int lowerLabelBound, int upperLabelBound)
{
var user = _authentication.CurrentUser;
if (user.IsInRole(Roles.CorporateInquiry) || user.IsInRole(Roles.StoreInquiry))
throw new InvalidOperationException("User must be a non-inquiry role.");
List<Fixture> fixturesToVoid = GetLabelsInRange(eventId, areaCode, lowerLabelBound, upperLabelBound).Where(f => f.StatusCode == FixtureStatus.Ready).ToList();
if (fixturesToVoid.Count < 1) return null;
// Void all old labels and tally the labels that to be recreated
// for each area involved.
var voidFixturesByArea = new Dictionary<int, int>();
foreach (var f in fixturesToVoid)
{
if (!voidFixturesByArea.ContainsKey(f.AreaCode))
voidFixturesByArea[f.AreaCode] = 1;
else
voidFixturesByArea[f.AreaCode]++;
f.StatusCode = FixtureStatus.VoidReplace;
_fixtureRepo.Update(f);
}
var storeEvent = _storeEventRepository.FindEvent(user.DefaultStore, eventId);
var lastUsedLabel = storeEvent.LastUsedLabelNumber;
var affectedAreas = new List<InventoryArea>();
// Create new labels for the affected areas.
foreach (var pair in voidFixturesByArea)
{
var area = _areaRepo.FindByKey(user.DefaultStore.GroupCode, user.DefaultStore.ID, eventId, pair.Key);
var fixtures = _fixtureBuilder.AddFixtures(lastUsedLabel.Value, area, pair.Value);
fixtures.ForEach(f => _fixtureRepo.Insert(f));
area.Fixtures = fixtures;
affectedAreas.Add(area);
}
// Update the store event counts.
var numberOfLabels = fixturesToVoid.Count();
storeEvent.LastUsedLabelNumber += numberOfLabels;
_storeEventRepository.Update(storeEvent);
return new InventoryAreaPrintContext(_barcodeGenerator) { InventoryAreas = affectedAreas, StoreEvent = storeEvent, Store = user.DefaultStore };
}
public class BarcodeGenerator : IBarcodeGenerator
{
private readonly BarCodeImage.CodeSetEncoder _codeSetEncoder;
public BarcodeGenerator(BarCodeImage.CodeSetEncoder codeSetEncoder)
{
_codeSetEncoder = codeSetEncoder;
}
public byte[] CreateBarcode(string barcodeText)
{
byte[] data;
var generator = new BarCodeImage(barcodeText, _codeSetEncoder, true)
{
InsetText = false,
Font = new Font(
FontFamily.GenericSansSerif,
10,
FontStyle.Regular,
GraphicsUnit.Pixel)
};
/**
* Keep the image dimensions at the same ratio as they will be displayed in the report.
* Currently the report is set to a height to width ratio of 1/5 so we set the image
* height to width at 1/5 as well. Otherwise the barcode will not scan properly.
**/
using (var image = generator.Render(50, 250))
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Jpeg);
data = ms.GetBuffer();
}
return data;
}
}