[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 343
  • Last Modified:

PHP Sockets

Hello,

I have reached about the end of my patience with this guys so I am hoping someone could let me know whats going on.

I think I know what the problem maybe but have no idea how to solve it.

If I can get away from showing the public the code I would appricate it as it's took me month's to develop to get this far.

Basicly I am using stream_socket_client in non blocking mode to connect to multiple smtp servers at the same time using stream_select.

Everything is working perfectly and I can achieve 600k + emails an hour to our opted in members list with one script so I am pritty happy about that.

The problem is when I try to use a large email copy i.e 200+ html lines things stop working...it seams to be a limit on fwrite and quite possibly fwrite is simply not sending all the lines to the smtp server to finish the connection.

Does any one know of any limits or to get around it using sockets/fwrite...I've tried sending a series of different fwrites but the moment I introduce too much combined html it fails.

Thanks so much for your help!



0
jayipeak
Asked:
jayipeak
  • 7
  • 4
1 Solution
 
level9wizardCommented:
jayipeak>>The problem is when I try to use a large email copy i.e 200+ html lines things stop working

Do you get an error message that you can share? Or does php just hang/freeze?
0
 
jayipeakAuthor Commented:
It's prrity hard to explain basicly SMTP looks for \r\n.\r\n at the end of a email message to know when it's reached the end, because of the write buffer which i am guessing is (8KB?) it never reaches that line so the connection just hangs.

I've tried stream_set_write_buffer but that doesn't seam to have any effect.
0
 
level9wizardCommented:
Is it possible to take either a manual or low-level packet approach to this? For example, maybe you could serialize or break the message into segments where each segment has some identifier that when arriving at SMTP can be rebuilt into a usable string.

It's hard to troubleshoot this without seeing any code - but maybe you could provide a tech-map of start to finish what's involved, and what interfaces/technologies are used along the way (i.e. what server OS, what scripts/externals/libs, what smtp software, etc)
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 
muganeCommented:
you might try using MULTIPART email
0
 
jayipeakAuthor Commented:
Ok Guys, just to update you.

I now know 100% that it's todo with fwrite/buffer...basicly by default when using fwrite it uses a 8KB buffer, because I setup the socket as a stream with stream_socket_client I can't seam to use stream_set_write_buffer which is werid it seams to have no affect...if I pop the connection into blocking mode before writing it works perfectly as there is no need for buffering.

the email I am sending is 40KB hense the issues, it's a shame the SMTP protocol doesn't allow you to send your email message in batches either way I need to increase fwrite's buffer.
0
 
level9wizardCommented:
jayipeak>>I need to increase fwrite's buffer.

Or as I mentioned, considering breaking the email into segments - is this a possibility? You could do all the segmenting into 8kb 'packets' in your php script prior to sending, but since you didn't really let us know what's going on the other end - I can't shed much light on what options you have to reconstruct them.
0
 
jayipeakAuthor Commented:
Hi level9wizard,

Thanks for your feedback.

The script as I mentioned is connecting to a SMTP servers and mailing out to our members, so we have no control over the other side! Would be a lot easier if that was the case!

Thanks Again
0
 
jayipeakAuthor Commented:
If there was a way to find out there is nothing left in the buffer after a fwrite call so I can call fwrite again with the remaining part of the message then great, although the best way would be to find a way of increasing the buffer before doing a fwrite.
0
 
jayipeakAuthor Commented:
And btw the only thing I could find in regards to the SMTP protocol intending to send it in parts would be a extension called `CHUNKING` but not all mail servers support it :-(
0
 
jayipeakAuthor Commented:
Well Guys I've found my own solution eventually...

fwrite returns the number of bytes written into the buffer (when i non blocking mode) I then keep a track of how much I've already written then come back to that socket after it's had a little time to send some data over.

Simple! but never seams simple when your pulling your hair out!

Here is a example:
while ($written_count < strlen($towrite))
{
       $temp = substr($towrite, $written, strlen($towrite)-$written_count);
       $actual_written = fwrite($w, $temp);
       $written_count += $actual_written;
       
       // DO SOMETHING ELSE WHILE WAITING or use `usleep(500)`
}

Open in new window

0
 
level9wizardCommented:
jayipeak >> so your breaking this into several chunks? That's basically what I said above -code.
0
 
jayipeakAuthor Commented:
Hi level9wizzard,

Basicly yeah, but because smtp doesn't accept you to send it via chunks there was no way of knowing how much was sent as the remote server only replies back when the full message has been sent...thankfully the return value of fwrite posed a idea of counting how many bytes went into the buffer so it could be handled at our side.

Thanks,
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 7
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now